GUI事件

时间:2016-06-22 15:01:39

标签: c# .net multithreading asynchronous async-await

我正在听一个关于UserControl(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
  4. 我尝试了什么:

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

    - &GT;因为我的事件处理程序不是异步的,所以不编译。

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

    - &GT;申请冻结

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

    - &GT;工作,但我正在跳跃,有一个更好的方法来做async / await。

1 个答案:

答案 0 :(得分:2)

您只需将处理程序标记为async

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

我知道不建议asyc使用返回类型void(通常应为TaskTask<sometype>),但如果事件需要那个签名,这是唯一的方式。

这样,控制流将在await语句处返回给调用者。当AsyncCall完成后,最终在 UI线程上的await之后恢复执行。