C#有关事件订阅和取消订阅的问题

冰冷的小爪 2015-06-01 10:45:33
在做串口通信的时候,往往会 发送一条命令给设备,然后等待接收,由于串口有DataReceive这个事件,使用异步通信非常方便,但是,往往我们只需要发送一条命令,然后等待回复(Sp.DataReceive +=sp_DataReceive),但是,这样子,要是这条命令发送没成功,重复发送,就会导致(Sp.DataReceive +=sp_DataReceive)多次,从而导致sp_DataReceive执行次数过多,如果命令是多样的,回复也是多样的,例如(针对CMD1,有Sp.DataRcieve +=sp_DataReceive_For_CMD1,针对CMD2,有Sp.DataRcieve +=sp_DataReceive_For_CMD2)。
现在想到能解决的办法,就是分别对sp_DataReceive_For_CMD1订阅的次数,sp_DataReceive_For_CMD2订阅的次数使用一个变量来标记,然后,如果有CMD3,Sp.DataRcieve +=sp_DataReceive_For_CMD3,那么执行之前就使用循环,多次执行Sp.DataRcieve -=sp_DataReceive_For_CMD1,或者Sp.DataRcieve -=sp_DataReceive_For_CMD2,直到订阅次数清空。
问题来了,有没有更加完美的解决办法?
...全文
505 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Poopaye 2015-06-01
  • 打赏
  • 举报
回复
就像1楼说的,这样只监听一次不就好了
class A
{
	SerialDataReceivedEventHandler _dataReceivedDelegate;

	public A(SerialPort serialPort)
	{
		serialPort.DataReceived += this.OnDataReceive;
	}

	void OnDataReceive(object sender, SerialDataReceivedEventArgs e)
	{
		if (this._dataReceivedDelegate != null)
			this._dataReceivedDelegate(sender, e);
	}

	public void SetListener(SerialDataReceivedEventHandler listener)
	{
		this._dataReceivedDelegate = listener;
	}
}
冰冷的小爪 2015-06-01
  • 打赏
  • 举报
回复
是的,只能有一个方法在监听,而且监听的方法要跟发送的命令对上号
Poopaye 2015-06-01
  • 打赏
  • 举报
回复
按你的意思任何时候只能有一个方法在监听?
冰冷的小爪 2015-06-01
  • 打赏
  • 举报
回复
Sp已经是全局的,我们的设备有很多命令,每个命令发送后,设备都会返回不同的答案,所以针对不同的命令,有不同的sp_DataReceive方法,而且同一个命令还可能发送多次,所以 Sp.DataReceive += Sp_ReceiveMethod 要频繁执行,而Sp_ReceiveMethod 可能是Sp_ReceiveMethod_2,Sp_ReceiveMethod_3,要看之前发送的是什么命令。由于根据C#中,使用+=来订阅事件,如果不及时取消订阅,那么如果我发送的是CMD2,而针对CMD1的 Sp_ReceiveMethod_1没有取消订阅,那么就会执行(此时)不需要执行的代码。 而就算我执行CMD1,若之前累计了很多+=Sp_ReceiveMethod_1,那么将会执行多次Sp_ReceiveMethod_1
於黾 2015-06-01
  • 打赏
  • 举报
回复
Sp.DataReceive +=sp_DataReceive写进load里只注册一次不就好了 除非你确定只发送一次,接收一次,这个对象就要dispose掉了 否则如果你需要多次反复发送接收,弄个全局Sp不好吗
冰冷的小爪 2015-06-01
  • 打赏
  • 举报
回复
#5楼有道理,这样做虽然代码条数还是差不多,但感觉好了很多 ,#6楼的话能不能具体一点?
john_QQ:2335298917 2015-06-01
  • 打赏
  • 举报
回复
学习了
引用 楼主 u013315639 的回复:
在做串口通信的时候,往往会 发送一条命令给设备,然后等待接收,由于串口有DataReceive这个事件,使用异步通信非常方便,但是,往往我们只需要发送一条命令,然后等待回复(Sp.DataReceive +=sp_DataReceive),但是,这样子,要是这条命令发送没成功,重复发送,就会导致(Sp.DataReceive +=sp_DataReceive)多次,从而导致sp_DataReceive执行次数过多,如果命令是多样的,回复也是多样的,例如(针对CMD1,有Sp.DataRcieve +=sp_DataReceive_For_CMD1,针对CMD2,有Sp.DataRcieve +=sp_DataReceive_For_CMD2)。 现在想到能解决的办法,就是分别对sp_DataReceive_For_CMD1订阅的次数,sp_DataReceive_For_CMD2订阅的次数使用一个变量来标记,然后,如果有CMD3,Sp.DataRcieve +=sp_DataReceive_For_CMD3,那么执行之前就使用循环,多次执行Sp.DataRcieve -=sp_DataReceive_For_CMD1,或者Sp.DataRcieve -=sp_DataReceive_For_CMD2,直到订阅次数清空。 问题来了,有没有更加完美的解决办法?
  • 打赏
  • 举报
回复
引用 2 楼 u013315639 的回复:
Sp已经是全局的,我们的设备有很多命令,每个命令发送后,设备都会返回不同的答案,所以针对不同的命令,有不同的sp_DataReceive方法,
这说明你没有搞懂 DataReceive 的含义。DataReceive是低级而具体的,达不到你要求的那个“针对不同命令”的层次,因此用到你的逻辑中就是不合适的。 如何从 DataReceive 之后的处理中解析出一个一个命令(消息),已经有了一些例子了。你应该学习一下这个层面的知识。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧