【问题标题】:Task asynchronous programming run synchronously [duplicate]任务异步编程同步运行[重复]
【发布时间】:2021-05-07 03:05:38
【问题描述】:

通过阅读以下指南https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/,我试图创建三个应该同时异步运行的任务,但它们实际上是同步运行的。我想知道我哪里错了

Task<double?[]> rainfallGridValuesTask = Rainfall.ValuesAsync(rainfallGridValuesRepo.GetAll());  //it takes 5s
Task<double?[]> rainfallAvgValuesTask = Rainfall.AveragesAsync(rainfallAvgGridValuesRepo.GetAll());  //it takes 5s
Task<double?[][]> rainfallAnomaliesTask = Rainfall.AnomaliesAsync(rainfallGridValuesRepo.GetAll());  //it takes 5s

方法如下:

public static async Task<double?[]> Values(IQueryable<RainfallGridValue> rainfallGridValues)
{
    double?[] outputValues = new double?[108];

    System.Threading.Thread.Sleep(5000);  //Simulate the time taken by the method
    return outputValues;
}

然后我尝试通过这种方式获取任务返回的值:

rainfallValueChart.Data = await rainfallGridValuesTask;
rainfallAverageChart.Data = await rainfallAvgValuesTask ;
rainfallAnomalyChart.Data = await rainfallAnomaliesTask ;

但是当我运行这段代码时,它会在三个 Async 方法上等待 5 秒,所以出了什么问题,如何同时运行它们并在所有任务完成后继续?

【问题讨论】:

  • 异步方法仅与“await”的第一次调用是异步的。将System.Threading.Thread.Sleep(5000); 替换为await Task.Delay(5000);
  • 异步就是更有效地使用单个线程。它不是关于并发和多线程应用程序。
  • 这些是否应该执行 5 秒的 CPU 密集型计算?那么您的模拟非常好,并且观察结果是有效的。他们应该执行 5 秒的 I/O 吗?然后你应该切换到await Task.Delay 进行模拟。
  • @Giox:只要实际方法在内部使用await,您应该使用await Task.Delay()进行模拟。如果他们没有在内部使用await,而是使用其他一些异步/重叠系统,例如 BeginXYZ/EndXYZ 或回调,您可以制作一个与可等待任务兼容的包装器。
  • 另外,请不要忽略编译器警告。有一个编译器警告字面意思是 Values 将同步运行。

标签: c# asynchronous task


【解决方案1】:

正如 cmets 所指出的,不要使用 System.Threading.Thread.Sleep(5000),而是使用 await Task.Delay(TimeSpan.FromSeconds(5));。这将模拟在每个等待任务中执行 5 秒的 I/O(而不是 5 秒的 CPU 计算)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2018-03-08
    • 2010-10-25
    • 2018-09-12
    相关资源
    最近更新 更多