Async函数过早结束
本文关键字:结束 函数 Async | 更新日期: 2023-09-27 18:16:03
让我们看看下面的代码:
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行。为什么呢?
您正在使用async void
,除非您正在处理事件,否则您不应该这样做。首先,你需要让你的函数返回一个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
,你的外部函数现在有一种方法来检测内部函数何时完全完成,而不仅仅是等待它的第一次延续。
你需要保持主线程,因为当新线程为任务产生时,它工作,但你的主线程甚至在任务完成之前就存在了。
你必须确保主线程在你的工作线程结束之前退出。
可以使用互斥锁