c# - 异步函数以严格顺序的方式执行

标签 c# asynchronous async-await

我正在尝试在 C# 中围绕 async await 进行思考。我编写了这个包含两个文件的小型 Windows 控制台应用程序。

Downloader.cs

namespace AsyncAwait
{
    public class Downloader
    {
        public async Task DownloadFilesAsync()
        {
            // In the Real World, we would actually do something...
            // For this example, we're just going to print file 0, file 1.
            await DownloadFile0();
            await DownloadFile1();
        }
        public async Task DownloadFile0()
        {
            int count = 0;

            while (count < 100)
            {            
               Console.WriteLine("Downloading File {0,1} ----> {1,3}%",0,count);
               Thread.Sleep(10);
               count++;
        }
        await Task.Delay(100);
        }

        public async Task DownloadFile1()
        {
           int count = 0;            
           while (count < 100)
           {                
              Console.WriteLine("Downloading File {0,1} ----> {1,3}%", 1, count);
              Thread.Sleep(10);
              count++;
           }
           await Task.Delay(100);
        }
    }
}

程序.cs

namespace AsyncAwait
{
    class Program
    {
        static void Main(string[] args)
        {
              Downloader d = new Downloader();
              d.DownloadFilesAsync().Wait();
              Console.WriteLine("finished");   
        }
    }
}

在输出中,我看到文件一个接一个地被下载(file1 后跟 file2)。我在 DownloadFile0DownloadFile1 的 while 循环中休眠。

我希望它们一起发生,就像不同的线程一样,而不是严格按顺序发生。据我了解,这就是 async 的全部意义所在?我的理解错了吗?如果现在我该如何解决这个问题?

最佳答案

在你的 DownloadFilesAsync 你需要这样做:

 public async Task DownloadFilesAsync()
    {
        // In the Real World, we would actually do something...
        // For this example, we're just going to print file 0, file 1.
        var task1 = DownloadFile0();
        var task2 = DownloadFile1();
        await Task.WhenAll(task1, task2).
    }

基本上,await 意味着您在转到下一行之前等待任务的执行。所以让任务执行,然后在最后等待 WhenAll。 另外,尝试阅读有关 ConfigureAwait(false) 的信息,它将使您免于死锁:)

更新 另外,将 Thread.Sleep 更改为 await Task.Delay(100); (模拟文件下载,实际使用异步函数进行文件下载) Thread.Sleep 意味着您的主线程将在它到达此行时立即休眠并且不会屈服,因此您的任务将在最终等待此行之前完成整个循环:await Task.Delay(100);然后执行转到 DownloadFile1。 另一方面,Task.Delay 产量和执行将转到 DownloadFile1,直到它遇到第一个 await。

关于c# - 异步函数以严格顺序的方式执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46678891/

相关文章:

python - 从python中的异步函数修改全局变量

c# - 异步运行同一方法的多个实例?

c# - 将多个来源合并到一个目的地

c# - 任务变量 ContinueWith,稍后等待?

c# - C# 控制台应用程序中的单线程异步/等待

javascript - javascript for 循环内的异步调用

javascript - 异步库中的 async.map 和 bluebird 中的 Promise.map 有什么区别?

c# - ASP.NET MVC 2 中制作按钮单击显示文本的最简单(正确)方法是什么?

c# - 如何使用 Roslyn 获取方法定义?

c# - 为什么在 WPF UI 线程中执行异步回调