InvokeとBeginInvokeの違いは、前者が同期(完了を待つ)で、後者が非同期(一種のfire-and-forget)であることです。しかし、どちらも、UIメッセージループにメッセージを投稿することによって動作し、そのメッセージに到達したときにデリゲートが実行されます。
InvokeRequiredプロパティは、呼び出しをすべて呼び出す必要があるか、または同期スレッドまたは非同期呼び出しを必要とするかどうかではなく、正しいスレッドに既に存在するかどうかを判断します。 InvokeRequiredがfalseの場合は、UIスレッド上で(理論的には)すでに実行されています。単純に同期アクションを直接実行することもできます(非同期で非同期に起動する必要がある場合はBeginInvokeを使用することもできます)。これは、InvokeRequiredがfalseの場合はInvokeを使用できないことを意味します。これは、現在のスレッドのメッセージループを継続する手段がないためです。上記のコードには大きな問題がありますが、必ずしもあなたが報告しているエラーではありません。 は、いずれの場合でもBeginInvokeを実際に使用します。再帰呼び出しを監視する場合は、以下同様です。
ただし、ウィンドウハンドルなしではどちらも使用できません。フォーム/コントロールがインスタンス化されていても初期化されていない場合(つまり、最初に表示される前)、まだハンドルがない可能性があります。また、フォームが閉じられた後など、Dispose()によってハンドルがクリアされます。いずれの場合も、ハンドルなしでは呼び出すことができないため、InvokeRequiredはfalseを返します。 IsDisposedをチェックすることができます。また、ハンドルが存在するかどうかを具体的にテストするプロパティIsHandleCreatedもあります。通常、IsDisposedがtrueの場合(またはIsHandleCreatedがfalseの場合)、アクションを単純に削除するなどの特殊なケースにパントします。
だから、あなたが望むのコードは、おそらくもっとようである:あなたがコントロールを表示する前に別のスレッドからコントロールを使用するつもりかやっている場合は
if (IsHandleCreated)
{
// Always synchronous. (But you must watch out for cross-threading deadlocks!)
if (InvokeRequired)
Invoke(new UpdateTextFieldDelegate(WriteToForm), finished, numCount);
else
WriteToForm(finished, numCount); // Call the method (or delegate) directly.
// Execution continues from here only once WriteToForm has completed and returned.
}
else
{
// Handle the error case, or do nothing.
}
あり、それはあなたのフォームが完全に初期化/作成される前に、あなたがイベントを起動しているように聞こえる、または別のスレッド上でいくつかの時点でどこそれはshouldnそうです。 –
タイマー(System.TimersまたはSystem.Threading)を実行している場合は、完全に構築されていないか、または処分されていないフォームでこのコードが実行されているかどうかを確認します。 –
このコードはどこにありますか、どのメソッドまたはイベントハンドラですか?答えのために – Kev