2009-04-18 6 views
0

検索が完了する前にアプリを閉じると、System.InvalidOperationExceptionエラーが発生します。 Form1_FormClosingを閉じると、すべてのスレッドが中止するように指示します。 1つのスレッドでは、フォームのコントロールの1つにテキストを変更するように指示するデリゲート関数を呼び出すfinalizeがあります。それが起こると、上記の例外が「追加情報:InvokeまたはBeginInvokeはウィンドウハンドルが作成されるまでコントロールで呼び出すことができません。クローズ時にC#GUIが処理する問題

これを修正するにはどうすればよいですか?私は、isClosingフラグを追加し、テキストを更新する前にそれをチェックすることができますが、ハックのように感じ、問題を隠している。どのように私はこれを正しく解決するのですか?

答えて

1

これは、管理対象のコントロールが破棄され、ハンドルがなくなったが、まだウィンドウが閉じていないために表示されるためです。

Invokeコールをラップする関数を作成し、Invokeを呼び出す前にIsHandleCreatedをチェックします。 IsHandleCreatedがfalseの場合は、Invokeに電話をかけることはできません。電話を無視することができます。

public static class ControlExtensions 
{ 
    public static TResult InvokeEx<TControl, TResult>(this TControl control, 
              Func<TControl, TResult> func) 
    where TControl : Control 
    { 
    if (!control.IsHandleCreated) 
     return default(T); 

    if (control.InvokeRequired) 
     return (TResult)control.Invoke(func, control); 
    else 
     return func(control); 
    } 

    public static void InvokeEx<TControl>(this TControl control, 
             Action<TControl> action) 
    where TControl : Control 
    { 
    control.InvokeEx(c => { action(c); return c; }); 
    } 
} 

だから今だけInvokeExであなたのスレッドから任意のInvoke Sをラップし、コントロールが配置され、もはやハンドルを持ってきたとき、それが処理されます。

this.InvokeEx(c => c.label1.Text = "Hello world"); 
1

私はサミュエルに同意するだけでなく、チェックしますIsDisposed

void Handler() 
{ 
    if (ctrl.IsDisposed || !ctrl.IsHandleCreated) return; 
    if (ctrl.InvokeRequired) 
    Invoke(...); 
    else { 
    ... 
    } 
}