C# wait/async的这种用法正确吗?

C# wait/async的这种用法正确吗?,c#,.net,asynchronous,async-await,task-parallel-library,C#,.net,Asynchronous,Async Await,Task Parallel Library,我是async/await新手,我想确保这种方法是正确的: public async Task DoHeavyWorkAsync() { await Task.Run(() => { getResponseFromFarawaySlowServerAndDoSomethingWithIt(); }); } public async void ConsumeAsync() { Task longRunningTask = DoHeavyWorkAs

我是async/await新手,我想确保这种方法是正确的:

public async Task DoHeavyWorkAsync() 
{
    await Task.Run(() => {
        getResponseFromFarawaySlowServerAndDoSomethingWithIt();
    });
}

public async void ConsumeAsync()
{
    Task longRunningTask = DoHeavyWorkAsync();
    // do a lot of other stuffs here that does not depend on DoHeavyWorkAsync()
    await longRunningTask;
}

这种使用async/await的方式正确吗?还是我做错了什么?

您可以做以下几件事:

  • DoHeavyWorkAsync
    中,您实际上不需要使用
    Wait Task.Run
    生成状态机,只需
    返回Task.Run

    public Task DoHeavyWorkAsync() 
    {
       return Task.Run(() => getResponseFromFarawaySlowServerAndDoSomethingWithIt());
    }
    
  • async void
    仅用于异步事件处理程序。如果您的异步方法正在返回
    void
    ,它应该返回一个
    任务

    public async Task ConsumeAsync()
    
  • 如果
    DoHeavyWorkAsync
    是基于IO的操作,则无需将其包装在
    任务中。运行
    ,因为它本身就是异步的。只需使用
    wait
    即可。更重要的是,你不应该这样做。相反,您应该让同步方法的调用方显式地使用
    Task.Run
    ,如果需要的话:

    public void DoHeavyWork()
    {
        getResponseFromFarawaySlowServerAndDoSomethingWithIt();  
    }
    
    然后显式地将其包装在调用方法中:

    Task.Run(DoHeavyWork);
    

  • 从API设计器的角度看,<强>我会考虑拆分方法<强> >代码> GraveAffaysFraceAdvayServer和DesignMethIn < <代码> >:

    getResponseFromFarawaySlowServer
    doSomething()

    然后,您只能使用异步包装器包装长时间运行的方法

    然后,使用将:

    var response = await getResponseFromFarawaySlowServerAsync();
    doSomething(response);
    
    另一件有点异味的事情是:
    getResponseFromFarawaySlowServer
    本身不是异步的。如果可能,应该在该方法中等待http调用或webservice调用本身。目前您正在创建新线程,thad什么都不做,请稍候。如果您等待http调用,则这是多余的

    所以相反

    string getResponseFromFarawaySlowServer(){
      string response = new WebClient().DownloadString(uri);
      ...
      return response
    }
    
    async Task<string> getResponseFromFarawaySlowServerAsync(){ Task.StartNew..
    
    string getResponseFromFarawaySlowServer(){
    字符串响应=新WebClient()。下载字符串(uri);
    ...
    返回响应
    }
    异步任务getResponseFromFarawaySlowServerAsync(){Task.StartNew。。
    
    你可以直接:

    async Task<string> getResponseFromFarawaySlowServerAsync(){
      string response = await new WebClient().DownloadStringAsync(uri);
      ...
      return response;
    }
    
    异步任务getResponseFromFarawaySlowServerAsync(){ 字符串响应=等待新的WebClient()。下载StringAsync(uri); ... 返回响应; }
    为什么要在需要时才启动它?此代码无法编译,您缺少
    ConsumeAncy
    中的
    async
    关键字这是桌面应用程序还是web应用程序?这是桌面应用程序如果您能够使
    GetResponseFromFarawaysLowserver和DoSomethingWithit
    异步,请执行此操作,而不是用
    T包装它询问。运行