2017-05-18 2 views
0

현재 외부 스레드에서 포커스가있는 창 양식을 닫으려고합니다. 문제는 "InvalidOperationException : 크로스 스레드 작업이 유효하지 않음"을 예상대로 발생시키는 form.Focused를 호출하여 속성에 액세스 할 수 없다는 것입니다. 다음으로 Invoke를 호출하려고 시도했지만 getter-method로 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 속성을 호출하는 여러 가지 방법을 살펴 보았지만 모든 소스는 컴파일러가 getter로 form.Focused 호출을 인식해야한다고 말하면서 지금 당황 스럽다.

form.Propertyname 호출이 작동하지 않는 경우 외부 스레드에서 양식의 속성 값을 호출하는 올바른 방법은 무엇입니까?

감사합니다.

+0

델리게이트 유형이 잘못되었으므로, 'Func '이 필요합니다. 그러나 이것이 실제 문제는 아니며, 기본적인 Threading 경주 버그이기 때문에 Application.OpenForms도 사용할 수 없습니다. UI 스레드에서 전체 메서드를 실행해야합니다. 이 메서드를 호출하는 코드에서 BeginInvoke()를 사용하십시오. –

+0

@HansPassant 주목, 고마워. 아마 나중에 두통으로부터 나를 구할 것입니다. – NikeTheSword

답변

0

Focused 속성은 "단순한 getter"가 아닙니다.

현재 포커스가있는 창을 컨트롤의 Handle 속성과 비교합니다. Handle 속성은 먼저 크로스 스레드 액세스를 확인합니다. 소스 코드에서
:

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.Invoke(new Func<bool>(() => f.Focused)) 

참고 : 사용 closeThisForm (의 널 (null) 동안) 대신 f의.

관련 문제