异步功能太早完成

bot*_*aio 2 c# multithreading asynchronous

我们来看看以下代码:

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());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我真的很困惑.这个代码不应该同步工作,因为我直接等待异步方法吗?从1000行文件中我只打印了76行.这是为什么?

Sco*_*ain 11

您正在使用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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你的旧方法无法知道内部任务是否完成,t.Wait()只是等到第一次非同步完成reader.ReadLineAsync(),通过返回Task你的外部函数现在有办法检测内部函数何时完全完成而不是等待它的第一个延续.