异步功能太早完成

时间:2015-10-05 19:44:35

标签: 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());
            }
        }
    }
}

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

2 个答案:

答案 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)

你需要保持主线程,因为当为该任务生成新线程时,它会起作用,但是即使任务完成,你的主线程仍然存在。

您必须确保主线程在工作线程完成之前退出。

愿你可以使用互斥锁