ダイアログまたはその他のユーザーインタラクションをポップする必要があるバックグラウンドスレッドで実行されているコードがあるためInvoke
、UIスレッドへの通常の呼び出しを行います。
Control.Invoke(SomeFunction);
void SomeFunction()
{
...
}
しかし、バグに遭遇しました。UIスレッドが呼び出しにすぐに応答しないことがありInvoke
ます。UIスレッドが現在、まだ返されていないクロスプロセスDCOM呼び出しを実行していたという事実まで追跡しました。DCOM呼び出しが返されると、関数が呼び出されますが、それまではInvoke
呼び出しがハングしたように見えました。
これに対する私の解決策は、タイムアウトを導入することでした:
ManualResetEvent invokeEvent = new ManualResetEvent();
var result = Control.BeginInvoke(SomeFunction, invokeEvent);
if (!invokeEvent.WaitOne(1000))
throw new Exception("Not responding");
Control.EndInvoke(result);
void SomeFunction(ManualResetEvent invokeEvent)
{
invokeEvent.Set();
...
}
これは「私のマシン感覚で動作する」で機能しましたが、いくつかの欠陥がありました。
(出典:codinghorror.com)
- まず、タイムアウトが発生した場合でも、関数は呼び出されます-DCOM呼び出しが実際に完全にハングしていなかった場合、最終的に実行されます
- 第二に、明らかな恐ろしい競合状態があります
- 最後に、全体の「Arrgh」性があります
最初の2つのことが解決できたとしても、私たちはまだ一般的な不快感を持っています。これを解決するためのより良い方法はありますか?