它们虽然挤在一起, 但是是分两次执行的,第一次点button 和第二次点button

解决方案 »

  1.   

    更奇特的是,如果在textBox1里输入C,在点击button1,则Invoke会执行3次,instrumentId会从A依次变为B和C。instrumentId是一个局部变量,每次点击button1就会被更新,但是程序表现得像是有谁在维护instrumentId的历史值。理解不能啊。。
      

  2.   

    当你输入B然后按Button的时候,语句执行到 _mdSpi.SubscribeMarketData(new[] {instrumentId}); 的时候如果触发了 RspSubMarketData 事件,那么执行的是你“输入A然后按Button”的时候注册的事件处理方法(并且那个匿名委托方法自动加载了外部变量instrumentId,值为“A”),因为当前只是执行到第二条语句,根本没有执行第三条语句。如果执行到第三条语句,应该也不会触发 Invoke 操作。只有当你第三次执行_mdSpi.SubscribeMarketData(new[] {instrumentId}); 的时候,才会把前两次注册的时间处理方法都执行,且第一次你注册的这个匿名委托的外部变量值为"A",而第二次注册的匿名委托事件处理方法的外部变量值为"B"。你的这个代码的逻辑异常混乱,我不知道你到底想要做什么。看你的代码,你在每一次点击Button之后,在触发了“之前注册的”一个或者多个 RspSubMarketData 事件处理方法之后,然后又立刻追加(累加)一个事件处理方法,留待下次一并触发。这是想执行什么逻辑呢?
      

  3.   


    当然是“维护instrumentId的历史值”啊。这就是匿名委托使用外部变量时的原理啊。如果你只是这里一处有如此的 += 语句,那么按说不太可能在输入C并点击button1之后就执行3次,执行2次才对。因为你的代码是在触发了事件之后才执行 += 语句的。除非,你的SubscribeMarketData 语句跟触发那个事件之间,是异步的。如果是异步的,那么输入C并且点击button1之后,有可能触发3个相同事件(你所说的触发3次事件),也有可能只触发2个,这就看 += 语句执行得是否快于事件触发行为了(因为+= 语句与事件触发行为可能是并行执行的,不知道谁先谁后)。
      

  4.   

    首先你要理清思路,不要稀里糊涂地。每一次点击Button时你都要执行 += 吗?
      

  5.   


    我是非专业、非业内人士,大牛见笑了。我想实现的东西其实很简单,在每次SubscribeMarketData之后,如果成功,_mdSpi会回答我,然后我做一次listView1.Items.Add()动作。结果我自己2B了,没意识到自己反复在订阅事件。然后那个执行几次的问题,我确实是第n次按下button,就会执行n次listView1.Items.Add。而且好像还是稳定出现的。那个事件确实是另外一个线程触发的。您的意思是,如果是同步的,那么我第一次按下button时,压根就不会执行listView1.Items.Add?
      

  6.   

    感觉问题出在这个地方
    _mdSpi.RspSubMarketData += (_, __) => Invoke(new Action(() =>
                {
                    listView1.Items.Add(instrumentId);
                }));
    给RspSubMarketData增加了多个处理函数,因此处理了多次
      

  7.   


    如果你的事件是在 SubscribeMarketData 方法里、且在同一个线程立刻出发的,那么显然第一次执行它的时候不可能执行事件处理代码。因为你的代码是在执行了 SubscribeMarketData 之后才注册的。
      

  8.   

    如果没有办法找到更好的地方去“唯一地”注册事件处理方法,那么我们通常会这样写:........
    obj.Subscribed -= obj_Subscribed;
    obj.Subscribed += obj_Subscribed;这样,确保不会用同一个方法去重复注册(响应)事件。
    另外,你注册的方法是“使用了外部变量的匿名委托”,这实际上就裹挟了额外的参数。你应该能够看出这种引用外部参数的意义。
    只有完成了注册之后,事件处理方法才能被回调。你应该能够看出注册和调用事件的流程的先后关系。