2017-09-22 4 views
0

WinForms 응용 프로그램에서 WinForm의 FormClosing 이벤트 중에 정리를하고 싶습니다. 정리 코드는 비동기입니다.WinForms가 FormClosing 이벤트 동안 작업을 계속 기다리는 동안 처리됩니다.

FormClosing의 투수는 다음과 같습니다

private async void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    await DoCleanupAsync(); 

    // we never get here as the Form is disposed almost as soon as the async cleanup-method executes; 
} 

로 : 무슨 일이에요

private async Task DoCleanupAsync() 
{ 
    Console.WriteLine("stopping..."); // This is output 
    await Task.Delay(2000); 
    Console.WriteLine("stopped");  // This is not 
} 

이 양식 정리 코드에 await를하기 전에 처분되고있다 완료됩니다.

덧붙여 말하자면, 이는 양식을 업데이트하려고 시도하는 경쟁 조건을 일으키는 것입니다 (단순화하기 위해 양식에 로그 출력이 포함되어 있다고 가정). 양식이 삭제 되었기 때문에 ObjectDisposedException이 발생합니다.

폐기()가 호출 될 때 내가 호출 스택을 보면, 내가이

가 system.windows.forms.dll! System.Windows.Forms.Control.ControlNativeWindow.OnMessage (심판에서 트리거되는 것 볼 수 있습니다 System.Windows.Forms.Message m) 알 수 없음

그래서 우리는 dispose가 FormClosing 이벤트에서 직접 트리거되는 것을 볼 수 있습니다.

나는 해키 같은 수행하여이 문제를 해결할 수 있습니다

private async void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    e.Cancel = true; 
    await DoCleanupAsync(); 
    this.FormClosing -= Form1_FormClosing; 
    Close(); 
} 

을하지만 실제로 무슨 일이 일어나고 있는지 이해하고 싶습니다!

+0

DoCleanupAsync()를 호출하기 전에 닫히지 않도록 'e'플래그를 설정해 보았습니까? – DiskJunky

+1

물론. _await_에 도달하면 함수가 반환되고 'Form1_FormClosing'이 호출 된 곳부터 실행이 계속됩니다. 'DoCleanupAsync();'가 끝날 때까지 실행이 멈춘다 고 생각하는 것 같지만'await'이 의미하는 것이 아닙니다. – oerkelens

+0

'async/await' 작업이 어떻게 작동하는지 더 자세히 읽어야합니다. 그러면 혼자서 답을 찾을 수 있습니다. – dymanoid

답변

1

실제로

에 무슨 일이 일어나고 있는지 때 awaitasync 방법, 당신의 Form1_FormClosing 방법의 호출자에게 제어 되돌아 간다. 그리고이 시점에서 e.Cancel 플래그를 설정하지 않으면 양식이 닫힙니다.

DoCleanupAsync에 의해 반환 된 Task이 완료되면 처리기 실행이 재개됩니다. 그러나 양식은 이미 닫혔습니다.

+0

감사합니다. 바보 같아요. 나는 Form-closing 이벤트의 '호출자'도 기다리고 있다고 가정하고있었습니다. 그러나 리턴 타입의 void가 주어지면 분명히 불가능합니다. – Ive