TPL异步等待 - 异步任务是否必须链接调用堆栈?

时间:2015-03-13 20:29:43

标签: c# asynchronous task-parallel-library async-await task

我的理解是,以下是不好的做法,因为它会阻止线程:

Task t = Task.Run(() => MyMethod());
t.Wait();

虽然以下内容不会阻止该主题:

await MyMethod();

但是,要使用await,必须在方法签名中使用async关键字,并返回Task而不是void,或Task<T>

但是,在n层应用程序中,如果你有一个巨大的调用堆栈,那么我们必须让每个调用方法都是async / Task,如LinqPad的以下简单示例所示:

async void Main()
{
    int i = await GetNumberD();
    i.Dump();
}

async Task<int> GetNumberD()
{
    return await GetNumberC();
}
async Task<int> GetNumberC()
{
    return await GetNumberB();
}
async Task<int> GetNumberB()
{
    return await GetNumberA();
}
async Task<int> GetNumberA()
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    return 7;
}

2 个答案:

答案 0 :(得分:2)

  

我们必须让每个调用方法都是异步/任务吗?

是的,如果在堆栈末尾调用的方法是异步方法,那就是。

请注意,文档建议使用“Async”后缀结束方法的名称:

async Task<int> GetNumberAsync()

答案 1 :(得分:-1)

你没有,请不要这样做。

你可以等待Task.Run

await Task.Run(() => MyMethod());

async Task Main()
{
    int i = await Task.Run( () => GetNumberD());
    i.Dump();
}

int GetNumberD()
{
    return GetNumberC();
}
int GetNumberC()
{
    return GetNumberB();
}
int GetNumberB()
{
    return GetNumberA();
}
int GetNumberA()
{
    return 7;
}

我强烈建议您阅读这篇文章:http://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html

编辑这不是正确的答案。作为评论,我误解了cpu绑定任务。