异步和等待,有点混乱

时间:2014-02-10 12:38:14

标签: c# multithreading asynchronous task-parallel-library c#-5.0

我正在参考this博客,该博客解释了.Net framework 4.5中await和async关键字的用法

我正在尝试使用这些关键字解决以下实时情况

我有两个设备Device1和Device2。这些设备使用串行端口(RS 232)连接到我的计算机。我有一个Windows应用程序,可以向这些设备发送命令     现在,最初我必须通过发送特定的RS-232命令来启动这两个设备。现在我可以同时完成这项工作并相应地更新UI。以下是解决此问题的代码

public class Device1 
{
    public async Task<int> Start(int sec)
    {
        Console.WriteLine("Device1 started @ : " + DateTime.Now.ToString());
        Task t = new Task(() => { Thread.Sleep(sec * 1000); });
        t.Start();
        await t;
        Console.WriteLine("Device1 finished @ : " + DateTime.Now.ToString());
        return 1;
    }         
}

public class Device2 
{
    public async Task<int> Start(int sec)
    {
        Console.WriteLine("Device2 started @ : " + DateTime.Now.ToString());
        Task t = new Task(() => { Thread.Sleep(sec * 1000); });
        t.Start();
        await t;
        Console.WriteLine("Device2 finished @ : " + DateTime.Now.ToString());
        return 1;
    }       
}

private async void button1_Click(object sender, EventArgs e)
    {
        Device2 d2= new Device2();
        Device1 d1= new Device1();

        await d2.Start(10);
        label1.Text = "d2 Started....";///It takes 10 sec to update this
        await d1.Start(5);///this line starts executing after 10 secs?  Why?
        label1.Text = "d1 Started...";

        MessageBox.Show("I am done...");///Get this message after 15 sec!!!
    }

现在我的理解是await d2.Start(10);await d1.Start(5);将同时运行并相应地更新UI。但事实并非如此。仔细查看Console.WriteLine statememts就可以证明它是完全的seqential调用    有人可以对此有更多的了解吗?

2 个答案:

答案 0 :(得分:4)

await关键字不会使等待的任务(分别为d2.Start(10)d1.Start(5)的结果)并行运行。它的作用是对编译器说“在等待的任务完成后让其余的方法运行”而不阻塞线程。

您可能希望阅读有关async/await个关键字的一些介绍,例如here

答案 1 :(得分:4)

我推荐async新手async intro;它最后有链接到最佳后续文档。

简而言之,正在发生的事情是你await完成任务。这将暂停该方法,直到完成这些任务。如果您想让它们同时运行,那么您可以将任务保存到变量(t1t2)中,然后等待它们(await Task.WhenAll(t1, t2);)。

P.S。不要在Task代码中使用Task.Start构造函数或async;请改用Task.Run