2016-06-12 75 views
0

我正在编写的类正在使用多线程,并且我已为此类创建了此扩展方法以便以线程安全方式提出事件。在引发线程事件时无法访问已处理的对象

static class MultiThreadHelper 
{ 
    public static object Raise(this MulticastDelegate eventToRaise, object sender, EventArgs e) 
    { 
     object retVal = null; 

     MulticastDelegate threadSafeMulticastDelegate = eventToRaise; 
     if (threadSafeMulticastDelegate != null) 
     { 
      foreach (Delegate d in threadSafeMulticastDelegate.GetInvocationList()) 
      { 
       var synchronizeInvoke = d.Target as ISynchronizeInvoke; 
       if ((synchronizeInvoke != null) && synchronizeInvoke.InvokeRequired) 
       { 
        retVal = synchronizeInvoke.EndInvoke(synchronizeInvoke.BeginInvoke(d, new[] { sender, e })); 
       } 
       else 
       { 
        retVal = d.DynamicInvoke(new[] { sender, e }); 
       } 
      } 
     } 

     //Return the value of the event invocation or null if none. 
     return retVal; 
    } 
} 

当我的形式,试图关闭一个挥之不去的线程仍在试图向警方报到,并提出不再有处理程序的事件。

我最终得到下面的错误...

enter image description here

发生该行错误之前,我可以运行什么样的检查?还有什么我可以做的或者我可以采取不同的方法来解决这个问题?

回答

2

我的第一个想法是ManifestBuilder在关闭时并未退出委托。确保您使用-=语法取消订阅。

+0

我在ManifestBuilder的FormClosing事件中这样做。但是我将它作为事件块中的最后一个动作。当我把它作为事件块中的第一个动作时,似乎提升了这个问题。我认为我的错误是让用户在我处理类对象之前取消订阅......虽然我不明白为什么这会起作用。 –

+0

挖掘更多...在FormClosing事件中,我会尝试调用将创建一个新线程的类的方法。然后,只要创建新的线程,我会退订。然后......一旦线程完成,它会发送一个事件(认为有一个订阅)。在处理多线程时,有没有办法检查任何订阅是否还活着?我的问题很简单,订阅事件 - >强制线程在定时器上发送事件 - >取消订阅 - >事件触发认为有订阅但没有订阅去。 –

+0

在进一步检查您的代码时,我会查看您获取对传入您的Raise方法的eventToRaise引用的位置。我能想到的唯一的事情就是你在表单处理之前的某个时间点分配了这个变量,并且取消订阅了事件,然后在表单被处理后使用它。 –

相关问题