程序在等待时退出

时间:2015-12-19 21:06:42

标签: c# async-await

我有一个while循环,应该重复该程序,直到满足某个条件。在这个循环中我调用异步函数,它为我打印一条消息。这是(简短)代码:

private void InitializeMessageSystem ( ) {
    do
    {
        // Do stuff
        await printMessage ("Hello World!");
        Console.ReadKey();
    } while (condition != true)
}

这里是函数printMessage()

private static async Task printMessage (string message, int spd = 1)
    {
        int delay = 50 / spd;

        string[] words = message.Split(' ');

        int index = 1;

        for (int word = 0; word < words.Length; word++)
        {
            char[] current = words[word].ToCharArray();
            if (index + current.Length > Console.WindowWidth)
            {
                Console.WriteLine();
                index = 1;
            }
            for (int c = 0; c < current.Length; c++)
            {
                Console.Write(current[c]);
                await Task.Delay(delay);
            }
            Console.Write(" ");
        }
    }

修改 来自主函数的调用:

static void Main (string[] args) 
{
InitializeMessageSystem();
Console.ReadKey();
}

问题
当我在功能尚未完成时按下某个键时,为什么我的程序会退出?我认为程序会等到Console.ReadKey(),直到函数printMessage()完成?

2 个答案:

答案 0 :(得分:16)

您的问题是await将程序的控制流程返回给函数的调用者。通常,当您等待的异步任务完成时,将继续执行。

因此,当您等待printMessage并且main等待键输入时,控制将返回到您的主函数。当您按下键main返回操作系统时,您的进程(包括所有异步任务)将终止。

InitializeMessageSystem更改为

private async Task InitializeMessageSystem ( )  

并将main中的代码更改为

InitializeMessageSystem().Wait();

在等待密钥之前等待InitializeMessageSystem完成。

答案 1 :(得分:1)

以下代码执行时没有任何错误或警告。但是,当您执行代码时,程序会静默退出。您可能期望的是程序等待任务完成,要求用户按任意键并退出。实际发生的情况是在执行await语句后,控件返回到调用步骤。在我们的情况下,在执行步骤await task;之后,在任务完成之前,控制权返回到调用步骤SomeTask();,程序退出。

class Program
{
    static void Main(string[] args)
    {
        SomeTask();
    }

    public static async void SomeTask()
    {
        Task task = Task.Run(() =>
        {
            System.Threading.Thread.Sleep(20000);
            Console.WriteLine("Task Completed!");
        });
        await task;
        Console.WriteLine("Press any key to exit");
        Console.ReadLine();
    }
}

要解决此问题,请将await添加到SomeTask();调用中,以便程序等待异步SomeTask()完成。您还应该更改返回类型 从空到任务的SomeTask()。

class Program
{
    static void Main(string[] args)
    {
        await SomeTask();
    }

    public static async Task SomeTask()
    {
        Task task = Task.Run(() =>
        {
            System.Threading.Thread.Sleep(20000);
            Console.WriteLine("Task Completed!");
        });
        await task;
        Console.WriteLine("Press any key to exit");
        Console.ReadLine();
    }
}