4

我有一个简单的async示例await,我正在尝试完成,并且执行没有像我预期的那样返回给调用者。这是顶级方法:

protected async void MyDDL_SelectedIndexChanged(object sender, EventArgs e)
{
  Task longRunningTask = LongRunningOperationAsync();
  DoOtherStuff1();
  DoOtherStuff2();
  DoOtherStuff3();
  await longRunningTask;
}

这是LongRunningOperationAsync无法按预期工作并同步运行的方法:

 private async Task LongRunningOperationAsync()
 {
   var myValues = await GetStuffViaLongRunningTask();
   //Code to work with myValues here...
 }

这里是定义GetStuffViaLongRunningTask

private async Task<IList<MyClass>> GetStuffViaLongRunningTask()
{

    //...Calls to get and build up IList<MyClass>
    return results;

}

问题是上面的代码没有DoOtherStuff1();我期望的那样返回给调用者并开始运行该方法。但是,与其调用我自己的方法并将其替换为await Task.Delay(10000);像所有简单示例所示的那样,代码将按预期工作:

 private async Task LongRunningOperationAsync()
 {
   //Returns to caller as expected:
   await Task.Delay(10000);
 }

使用上面代码的调用者的状态longRunningTask是 aWaitingForActivation而不是RanToCompletion,表明它仍在处理中。

你可能会说我的GetStuffViaLongRunningTask()方法运行得太快了,我就是看不到结果。但是,它总是需要 3-7 秒才能运行,并且您可以在调试时知道调用是阻塞的和同步的。

我在这里做错了什么,所以当在该方法中到达要调用的单词LongRunningOperationAsync()时,我的调用不会异步工作?awaitLongRunningOperationAsync

4

2 回答 2

3

假设这//...Calls to get and build up IList<MyClass>是同步的 CPU 绑定工作,那么问题是在它结束或第一次调用GetStuffViaLongRunningTask之前不会返回。await您应该在该方法上收到编译器警告,因为它是一个async没有其中的方法await

相反,该方法根本不应该是async,向它的调用者清楚地表明它是同步工作。只需将签名调整为:

private IList<MyClass> GetStuffViaLongRunningTask()

然后在调用它时使用Task.Run以确保长时间运行的 CPU 绑定工作在另一个线程中完成:

private async Task LongRunningOperationAsync()
{
    var myValues = await Task.Run(() => GetStuffViaLongRunningTask());
    //Code to work with myValues here...
}
于 2013-10-07T19:20:56.423 回答
1

//...Calls to get and build up IList<MyClass>

您需要向我们展示正在拨打的电话。如果您想在这种结构中使用 async/await,那么您需要进行异步调用。

如果您的GetStuffViaLongRunningTask函数没有进行异步调用,那么您可以启动一个新任务,如下所示:

private Task<IList<MyClass>> GetStuffViaLongRunningTask()
{
    return Task.Factory.StartNew(() =>
    {
        //...Calls to get and build up IList<MyClass>
        // You can make synchronous calls here
        return list;
    });
}
于 2013-10-07T19:22:20.840 回答