2016-06-12 4 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イベントでは、新しいスレッドを作成するクラスのメソッドを呼び出そうとします。その後、新しいスレッドが作成されると、私は退会します。その後、スレッドが終了するとイベントを送信します(購読されていると考えます)。マルチスレッドを扱うときにANYサブスクリプションが生存しているかどうかを確認する方法はありますか?私の問題はシンプルで、イベントを購読する - >スレッドで強制的にイベントをタイマーで送信する - > unsubscribe - >イベントは、サブスクリプションがあると思って起動しますが、サブスクリプションはありません。 –

+0

あなたのコードをさらに調べたら、Raiseメソッドに渡すeventToRaiseへの参照をどこで取得するかを調べます。私が考えることができるのは、フォームが破棄される前の時点でその変数を割り当て、イベントがサブスクライブされていないということだけです。そして、フォームが破棄された後にその変数を使用することです。 –

関連する問題