2016-06-22 4 views
-1

나는 듣고있어한다는 UserControl을 (의 WinForm)에서 이벤트를했습니다 :이 호출 할 수있는 방법비동기 호출

public async Task<SomeResult> AsyncCall(); 

:

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = ?await? _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

_businessObject.AsyncCall() 다음과 같은 서명이

  1. 는 GUI 스레드
  2. 인을 차단하지 않음 : 비동기 방식 동안 내 비동기 메서드가 호출 된 후 ApplySomethingOnTheGuiBasedOnTheResult을 호출 할 수 있습니다.
  3. 올바른 (GUI) 스레드로 ApplySomethingOnTheGuiBasedOnTheResult을 호출 할 수 있습니다.

내가 뭘하려 :

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = await _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

- 내 이벤트 처리기가 비동기 아니기 때문에> 컴파일되지 않습니다.

public void OnSomething(SomeEventArgs args){ 
    SomeResult result = _businessObject.AsyncCall().Result; 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

-> 응용 프로그램

public void OnSomething(SomeEventArgs args){ 
    _businessObject.AsyncCall().ContinueWith(t=>{ 
     if(InvokeRequired){ 
      Invoke(new Action(()=>ApplySomethingOnTheGuiBasedOnTheResult(t.Result))); 
     } 
    }); 
} 

동결 -> 작품을,하지만 난 비동기/await를 함께 할 수있는 더 좋은 방법이 있다는 것을 호핑했다. 이벤트가 그 서명을 요구하는 경우

public async void OnSomething(SomeEventArgs args) 
{ 
    SomeResult result = await _businessObject.AsyncCall(); 
    ApplySomethingOnTheGuiBasedOnTheResult(result); 
} 

를 내가는 (일반적으로는 Task 또는 Task<sometype>해야한다) 반환 형식 voidasyc를 사용하지 않는 것이 좋습니다 알고 있지만 :

답변

2

당신은 단순히 async로 핸들러를 표시해야 , 유일한 방법입니다.

이렇게하면 제어 흐름이 await 문으로 호출자에게 반환됩니다. AsyncCall이 완료되면 UI 스레드의await 뒤에 실행이 결국 으로 다시 시작됩니다.

+2

나는 OP와 미래의 독자들에게 '비동기 무효화 (void)'라고 써야 할 유일한 곳이 바로 이런 이벤트 핸들러를 할 때이다. 만약 당신이 이벤트 처리기를 쓰지 않는다면 당신은'async Task'를 수행해야합니다. –

+0

@ScottChamberlain 맞습니다. –

+0

문제 없음, 편집을하지 않아도 +1 했음 :) –