创建了以下控制台应用程序后,我有点困惑为什么它似乎是同步运行而不是异步运行:
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var total = CreateMultipleTasks();
stopwatch.Stop();
Console.WriteLine("Total jobs done: {0} ms", total.Result);
Console.WriteLine("Jobs done in: {0} ms", stopwatch.ElapsedMilliseconds);
}
static async Task<int> CreateMultipleTasks()
{
var task1 = WaitForMeAsync(5000);
var task2 = WaitForMeAsync(3000);
var task3 = WaitForMeAsync(4000);
var val1 = await task1;
var val2 = await task2;
var val3 = await task3;
return val1 + val2 + val3;
}
static Task<int> WaitForMeAsync(int ms)
{
Thread.Sleep(ms);
return Task.FromResult(ms);
}
}
运行应用程序时,输出为:
Total jobs done: 12000 ms
Jobs done in: 12003 ms
我本以为会是这样的:
Total jobs done: 12000 ms
Jobs done in: 5003 ms
这是因为当我使用 Thread.Sleep 方法时它停止了整个应用程序的进一步执行吗?还是我在这里遗漏了一些重要的东西?
最佳答案
即使您像其他答案所建议的那样转换为使用 Task.Run
或 Task.Delay
,您也应该避免使用阻塞 Task.WaitAll
async
方法 中的任何位置,尽可能多。混合异步和同步代码通常不是一个好主意,它会增加冗余阻塞线程的数量并促进死锁。
相反,使用 await Task.WhenAll
并将阻塞等待移动到顶层(即,在这种情况下为 Main
方法):
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var total = CreateMultipleTasks();
total.Wait();
stopwatch.Stop();
Console.WriteLine("Total jobs done: {0} ms", total.Result);
Console.WriteLine("Jobs done in: {0} ms", stopwatch.ElapsedMilliseconds);
}
static async Task<int> CreateMultipleTasks()
{
var task1 = Task.Run(() => WaitForMeAsync(5000));
var task2 = Task.Run(() => WaitForMeAsync(3000));
var task3 = Task.Run(() => WaitForMeAsync(4000));
await Task.WhenAll(new Task[] { task1, task2, task3 });
return task1.Result + task2.Result + task3.Result;
}
static int WaitForMeAsync(int ms)
{
// assume Thread.Sleep is a placeholder for a CPU-bound work item
Thread.Sleep(ms);
return ms;
}
}
在旁注中,查看 Stephen Toub 的 "Should I expose asynchronous wrappers for synchronous methods?"和 "Should I expose asynchronous wrappers for synchronous methods?"
关于c# - C# 中的异步方法不是异步的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23603526/