2016-06-22 206 views
-1

我已經上用戶控件(WinForm的)一個事件,我聽着:異步調用

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

_businessObject.AsyncCall()具有以下特徵:

public async Task<SomeResult> 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做到這一點。

回答

2

您只需標記您的處理程序爲async

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

我知道這是不推薦使用asyc返回類型爲void(通常應該是TaskTask<sometype>),但如果事件需要簽名,這是唯一的方法。

這樣控制流程將返回給await聲明中的調用者。當AsyncCall完成時,在UI線程上,await後最終執行執行。

+2

我只是想強調OP和將來的讀者,唯一的地方,你應該寫'異步無效'是當你做這樣的事件處理程序。如果你不寫一個事件處理程序,你應該做'異步任務'@ –

+0

@ScottChamberlain的權利,我在你評論的時候添加了這個。 –

+0

沒問題,我給你一個+1,即使沒有編輯:) –