等待Task.Delay在if函数中表现得很奇怪

时间:2018-01-16 17:55:18

标签: c# async-await task

所以即时尝试在富文本框中创建一些文本动画。 我猜我可以使用计时器获得相同/甚至更好的结果但是语法有点难以理解(我已经为+ - 50个小时编程了)

使用await Task.Delay方法,但它的行为与预期不同

private async void WriteText(string text, int delay)
    {
        await Task.Delay(delay);
        rtbOutput.AppendText(text);
    }

private void button1_Click(object sender, EventArgs e)
    {
        WriteText("string 1 \n", 1000);
        WriteText("string 2 \n", 2000);
        WriteText("string 3 \n", 500);
    }
//richTextBox reads
    //    string 3
    //    string 1
    //    string 2

虽然我希望程序等待WriteText的预期延迟("字符串1"然后运行第二个WriteText("字符串2")

程序似乎非常快速地读取3种方法,并且只在延迟时间输出。

我可以解决这个问题bij只是将第一个延迟添加到第二个并且它会表现得很好

然后我尝试了一个if方法

private async void WriteTextChain(string text, int delay, int chain)
    {
        for (int i = 0; i < chain; i++)
        {
            rtbOutput.AppendText(text);
            await Task.Delay(delay);
        }
    }

 private void button2_Click(object sender, EventArgs e)
    {
        WriteTextChain("string 1 \n", 1000, 3);
        WriteTextChain("string 2 \n", 300, 6);
    }
    /* output reads
        string 1
        string 2
        string 2
        string 2
        string 2
        string 1
        string 2
        string 2
        string 1
    */

这个输出让我大吃一惊。怎么了? 我期待 string 2,string 2,string 2,String 1 sequence

任何人?

1 个答案:

答案 0 :(得分:2)

那是因为一旦你启动了异步函数,特别是一旦返回void,就会在新的上下文中执行(可以在同一个线程上,但在大多数情况下都不是)。

您需要更改代码:

private async Task WriteTextChain(string text, int delay, int chain)
// returning Task allows you to await call to this function
    {
        for (int i = 0; i < chain; i++)
        {
            rtbOutput.AppendText(text);
            await Task.Delay(delay);
        }
    }

 private async void button2_Click(object sender, EventArgs e)
    {
        await WriteTextChain("string 1 \n", 1000, 3); // await makes execution of next line to wait for this line completion
        await WriteTextChain("string 2 \n", 300, 6);
    }
    /* output reads
        string 1
        string 1
        string 1
        string 1
        string 2
        string 2
        string 2
        string 2
        string 2
    */

TPL库有相当多的学习曲线,但还在继续进行实验。它变得更好