2017-05-18 1 views
0

私は現在、外部スレッドからフォーカスを持っているウィンドウフォームを閉じようとしています。問題は、単に "InvalidOperationException:クロススレッド操作が有効でない"という予期したものを投げるform.Focusedを呼び出すことによってプロパティにアクセスできないことです。次に、Invokeを呼び出しようとしましたが、GetterメソッドとしてControl.Focusedを認識しません。ここでは、現在のコードは次のとおりです。他のスレッドからWindowsフォームのプロパティ値をどのように呼び出すのですか?

private void CloseFormWithFocus() 
{ 
    FormCollection openForms = Application.OpenForms; 
    Form closeThisForm = null; 

    foreach (Form f in openForms) 
    { 
     // Here's the part that does not compile 
     if (closeThisForm.Invoke((MethodInvoker)delegate() { closeThisForm.Focused; });) 
     { 
      closeThisForm = f; 
     } 
    } 
} 

は、しかし、私を混乱させるどのような(おそらく、スレッドセーフではない)プロパティをform.Nameするために比較することによって、フォームを閉じ、他のほとんど同一の方法は、私は単純に、このようにそれを呼び出すことができますということです。

private void CloseForm(string formName) 
{ 
    FormCollection openForms = Application.OpenForms; 
    Form closeThisForm = null; 

    foreach (Form f in openForms) 
    { 
     if (f.Name == formName) 
     { 
      closeThisForm = f;      
     } 
    } 
} 

私はプロパティゲッターを呼び出すさまざまな方法を見てきましたが、すべてのソースは、コンパイラーがgetterとしてのform.Focusedを認識する必要があると単純に述べています。

form.Propertyname呼び出しが機能しない場合、外部スレッドからフォームのプロパティ値を呼び出す正しい方法(または可能であれば単純に読み取ります)は何ですか?

ありがとうございます。

+0

デリゲートタイプが間違っています。あなたは 'Func 'が必要です。しかし、それは本当の問題ではなく、基本的なスレッドレースのバグだとすれば、Application.OpenFormsを使用することはできません。メソッド全体をUIスレッドで実行する必要があります。このメソッドを呼び出すコードでBeginInvoke()を使用します。 –

+0

@HansPassantありがとう、ありがとう。おそらく後で頭痛から私を救うでしょう。 – NikeTheSword

答えて

0

Focusedプロパティは「単なるゲッター」ではありません。

現在のフォーカスされたウィンドウとコントロールのHandleプロパティを比較します。 Handleプロパティは、最初にクロススレッドアクセスをチェックします。ソースコードから

f.Invoke(new Func<bool>(() => f.Focused)) 

注:

public virtual bool Focused { 
     get { 
      return IsHandleCreated && UnsafeNativeMethods.GetFocus() == Handle; 
     } 
    } 

public IntPtr Handle { 
     get { 
      if (checkForIllegalCrossThreadCalls && 
       !inCrossThreadSafeCall && 
       InvokeRequired) { 
       throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall, 
                   Name)); 
      } 

あなたは、このようInvokeから値を返すことができますが、代わりにfの(そのヌルながら)closeThisFormを使用しました。

関連する問題