取消订阅活动仍然会多次被解雇,如何阻止它? [英] Unsubscribing from an event still it's getting fired many times, how to stop it?
问题描述
首先我正在订阅一个事件,然后在该事件发生时将执行的方法我取消订阅它。但我仍然认为它被解雇了很多次。
我尝试过:
使用System;
使用System.Collections.Generic;
使用System.IO;
使用System.IO.Ports;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
namespace SerialPortHexCommunication
{
public class Program
{
private static bool unsubscribe = false;
static void Main(string [] args)
{
SerialPort port = new SerialPort();
port.PortName =COM5;
port.Parity = Parity.None;
port.BaudRate = 9600;
port.DataBits = 8;
port.StopBits = StopBits.One;
if(port.IsOpen)
{
port.Close();
port.Dispose();
}
port.Open();
byte [] bytesToSend = new byte [6] {0xD0,0xF2,0xFF,0x00,0x06,0xC7};
port.Write(bytesToSend,0,bytesToSend.Length);
port.DataReceived + = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
port.DataReceived - = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
Console.ReadKey();
port.Close();
port.Dispose();
}
}
}
使用System;
使用System.Collections.Generic;
使用System.IO.Ports;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
namespace SerialPortHexCommunication
{
public class cEventHandler
{
public void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{// this In
//应该只打印一次数据接收消息,因为我取消订阅但是多次打印。
Console.WriteLine(在数据接收中);
SerialPort port =(SerialPort)sender;
port.DataReceived - = new SerialDataReceivedEventHandler(DataReceivedHandler);
int bytes = port.BytesToRead;
byte [] buffer = new byte [bytes];
if(port.BytesToRead> 1)
{
port.Read(buffer,0,bytes);
}
foreach(缓冲区中的字节项)
{
Console.WriteLine(item);
}
port.DataReceived - = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
//Console.ReadKey();
}
}
}
请看看你的代码!
为什么要这样写:
SerialPort port = new SerialPort();
...
if(port.IsOpen)
{
port.Close();
port.Dispose();
}
port.Open();如果它是一个新端口,它就无法打开 - 这也是一样,因为你的应用程序会立即崩溃试图成熟你刚刚处置过的一个端口......
第二点要注意的是,多个DataReceived事件正是你应该期待的:串行数据被称为因为它以串行方式逐字节到达,而不是作为信息的托管包:每个字节都可能导致单独的DataReceived事件被触发。
I两天前告诉你这个!
DataReceived事件应该在调用
Open()$之前订阅p $ p>方法SerialPort类。
根据您的结果事件被多次调用 - 在我的只有在来自另一个配对端口的任何响应的情况下才会调用case事件。
对于ex。配对端口是 - COM5< - > COM3所以当任何响应来自COM3端口时,将调用DataReceived事件。
无需取消订阅该事件。
Quote:
port .DataReceived + = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
port.DataReceived - = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
您已为事件添加了两个处理程序。因此,每次引发事件时,您的事件处理程序都会被调用两次。
引用:
port.DataReceived - = new SerialDataReceivedEventHandler(new cEventHandler()。DataReceivedHandler);
该行将有没有效果。
当从事件中删除指向实例方法的委托时,委托指向的对象引用将作为其标识的一部分包含在内。由于您正在创建类的新实例,因此您创建的委托不等于该事件的任何已注册处理程序,因此删除它不会执行任何操作。
之前的port.DataReceived - =新的SerialDataReceivedEventHandler(DataReceivedHandler);
行应该已经删除了处理程序,所以你可以删除这一行。
First I am subscribing to an event and then in the method which will be executed when that event occurs i am unsubscribing it.But still I think it is getting fired many times.
What I have tried:
using System; using System.Collections.Generic; using System.IO; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SerialPortHexCommunication { public class Program { private static bool unsubscribe=false; static void Main(string[] args) { SerialPort port = new SerialPort(); port.PortName = "COM5"; port.Parity = Parity.None; port.BaudRate = 9600; port.DataBits = 8; port.StopBits = StopBits.One; if (port.IsOpen) { port.Close(); port.Dispose(); } port.Open(); byte[] bytesToSend = new byte[6] { 0xD0, 0xF2, 0xFF, 0x00, 0x06, 0xC7 }; port.Write(bytesToSend, 0, bytesToSend.Length); port.DataReceived += new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler); port.DataReceived -= new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler); Console.ReadKey(); port.Close(); port.Dispose(); } } }
using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SerialPortHexCommunication { public class cEventHandler { public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {//this In data receive message should be printed only once //as i am unsubscribing but it get printed many times. Console.WriteLine("In data receive"); SerialPort port = (SerialPort)sender; port.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler); int bytes = port.BytesToRead; byte[] buffer = new byte[bytes]; if (port.BytesToRead > 1) { port.Read(buffer, 0, bytes); } foreach (byte item in buffer) { Console.WriteLine(item); } port.DataReceived -= new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler); //Console.ReadKey(); } } }
Please, look at your code!
Why would you write this:
SerialPort port = new SerialPort(); ... if (port.IsOpen) { port.Close(); port.Dispose(); } port.Open();If it's a new port, it can't be open - which is just as well, as your app would then crash immediately as you tried to oipen a port you had just Disposed...
The second thing to note is that multiple DataReceived events are exactly what you should expect: Serial data is called that because it arrives in a serial fashion, byte by byte instead of as a "managed packet" of information: each byte can cause a separate DataReceived event to fire.
I told you this two days ago!
DataReceivedevent should be subscribed before calling
Open()method of
SerialPortclass.
As per your result event is called many times- In my case event will be called only in case of any response comes from another paired port.
For ex. Paired ports are - "COM5" <-> "COM3" so when any response will come from "COM3" port then theDataReceivedevent will be called.
There is no need to unsubscribe the event.
Quote:
port.DataReceived += new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler); port.DataReceived -= new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler);
You've added two handlers to the event. Therefore, every time the event is raised, your event handler will be called twice.
Quote:port.DataReceived -= new SerialDataReceivedEventHandler(new cEventHandler().DataReceivedHandler);
That line will have no effect.
When a delegate pointing to an instance method is removed from an event, the object reference to which the delegate points is included as part of its identity. Since you're creating a new instance of your class, the delegate you create is not equal to any of the registered handlers for the event, so removing it doesn't do anything.
The previousport.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
line should already remove the handler, so you can just delete this line.
这篇关于取消订阅活动仍然会多次被解雇,如何阻止它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!