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函数过早结束

您正在使用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,你的外部函数现在有一种方法来检测内部函数何时完全完成,而不仅仅是等待它的第一次延续。

你需要保持主线程,因为当新线程为任务产生时,它工作,但你的主线程甚至在任务完成之前就存在了。

你必须确保主线程在你的工作线程结束之前退出。

可以使用互斥锁