2009-04-18 4 views
0

검색이 끝나기 전에 응용 프로그램을 닫을 때 System.InvalidOperationException 오류가 발생합니다. Form1_FormClosing 닫을 ​​때 모든 스레드가 중단 할 말해. 하나의 스레드에서 양식의 컨트롤 중 하나가 텍스트를 변경하도록 지시하는 대리자 함수를 호출하는 finalize가 있습니다. 그 때 "추가 정보 : Invoke 또는 BeginInvoke 창 핸들을 만들 때까지 컨트롤에서 호출 할 수 없습니다"예외가 발생합니다.닫기 C# GUI에서 처리하는 문제

이 문제를 해결하려면 어떻게해야합니까? 나는 텍스트를 업데이트하기 전에 isClosing 플래그를 추가하고 검사 할 수 있지만 해킹과 같은 문제를 감추고 있습니다. 이 문제를 올바르게 해결하려면 어떻게해야합니까?

답변

1

관리되는 컨트롤이 삭제되어 더 이상 핸들이 없지만 아직 창을 닫지 않아 아직 볼 수 없기 때문에 이러한 현상이 발생합니다.

Invoke 전화를 걸고 Invoke을 호출하기 전에 IsHandleCreated을 확인하는 함수를 만들 수 있습니다. IsHandleCreated이 거짓이면 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의 포장 및 컨트롤이 배치되고 더 이상 핸들이되었을 때 그것을 처리합니다.

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

나는 사무엘 동의, 또한 확인 할 IsDisposed :

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