让我们看看以下代码:
class C
{
static void Main(string[] args)
{
Task t = new Task(DoSthAsync);
t.Start();
t.Wait();
Console.WriteLine("Finished?");
}
static async void DoSthAsync()
{
using (StreamReader reader = new StreamReader("file.txt"))
{
int i = 1;
while (!reader.EndOfStream)
{
Console.WriteLine("{0}: {1}", i++, await reader.ReadLineAsync());
}
}
}
}
我真的很困惑。这个代码不应该同步工作,因为我直接等待异步方法吗?从1000行文件中我只打印了76行。那是为什么?
答案 0 :(得分:10)
您正在使用async void
you should never do unless you are working with events。首先,您需要让函数返回Task
而不是void,然后必须使用Task.Run
而不是new Task
,以便它可以为您处理异步函数。
static void Main(string[] args)
{
Task t = Task.Run(() => DoSthAsync()); // "Task.Run((Func<Task>)DoSthAsync)" would also work.
t.Wait();
Console.WriteLine("Finished?");
}
static async Task DoSthAsync()
{
using (StreamReader reader = new StreamReader("file.txt"))
{
int i = 1;
while (!reader.EndOfStream)
{
Console.WriteLine("{0}: {1}", i++, await reader.ReadLineAsync());
}
}
}
你过去的方式无法知道内部任务是否完整,t.Wait()
只等到reader.ReadLineAsync()
的第一次非同步完成,通过返回Task
你的外部函数现在有一种方法可以检测内部函数何时完全完成,而不仅仅是等待它的第一次继续。
答案 1 :(得分:-1)
你需要保持主线程,因为当为该任务生成新线程时,它会起作用,但是即使任务完成,你的主线程仍然存在。
您必须确保主线程在工作线程完成之前退出。
愿你可以使用互斥锁