我正在尝试在 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
)。我在 DownloadFile0
和 DownloadFile1
的 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/