C#task.wait方法调用未完成

jam*_*ood 0 c# asynchronous task

我试图更好地理解C#中的任务和异步操作,我已经运行了这个示例程序,但我对输出感到困惑.当我运行它时,程序有时不会在CallMethod中输出Console输出

int length = await task
Run Code Online (Sandbox Code Playgroud)

有时确实如此,但当我取消注释时

Console.ReadLine()
Run Code Online (Sandbox Code Playgroud)

它总是运行所有的CallMethod.

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Tasks1
{
    class Program
    { 
        static void Main(string[] args)
        {
            Task task = new Task(CallMethod);
            task.Start();
            task.Wait();
            //Console.ReadLine();
        }

    static async void CallMethod()
    {
        string filePath = "/Users/testname/Projects/Tasks1/Tasks1/Sample.txt";
        Task<int> task = ReadFile(filePath);

        Console.WriteLine("Other Work 1");
        Console.WriteLine("Other Work 2");
        Console.WriteLine("Other Work 3");

        int length = await task;
        Console.WriteLine(" Total Length: " + length);

        Console.WriteLine("After work 1");
        Console.WriteLine("After work 2");

    }

    static async Task<int> ReadFile(string file)
    {
        int length = 0;

        Console.WriteLine("File reading is starting");

        using (StreamReader reader = new StreamReader(file))
        {
            string s = await reader.ReadToEndAsync();

            length = s.Length;
        }
        Console.WriteLine("File reading is complete");
        return length;
    }


}
}
Run Code Online (Sandbox Code Playgroud)

没有完成CallMethod 完成CallMethod

Mar*_*ell 7

async void- 它总是async void:)基本上,async void除非你非常清楚为什么要使用它,否则不要使用它.调用路径无法知道a的完成状态async void,因此从调用者的角度来看它将运行到第一个非同步await.在那之后,你处于线程竞争的场景中.它不能参与最外层Wait()(或await),因为它不报告状态.当所有非后台线程完成时,exe退出,因此:有时它可能有效,大部分都不行.添加Console.ReadLine()它等待更长时间的力量,因此它的工作原理.

基本上:CallMethod回报Task.

顺便说一句:在最新的C#版本中,你也可以制作你的Main方法async:

    static async Task Main(string[] args) {...}
Run Code Online (Sandbox Code Playgroud)

然后你可以await在你的Main.你应该Wait()完成一项任务的次数几乎为零; 通常你应该更喜欢await.