使用async / await或其他东西

时间:2016-05-16 14:17:48

标签: c# asynchronous serial-port async-await

我正在编写一个程序,它与我设计的一些控制硬件进行通信。硬件驱动电机,我要做的第一件事就是初始化电机。 硬件是通讯控制的,所以我只需通过USB向硬件发送消息即可。 要初始化电机,我必须发送2条消息;在我发送第一个之后,它将电机移向一个传感器,当它重新接通时,它停止并向我发回一条消息,告诉我它已停止,此时我发送另一条消息告诉它驱动电机进入相反的方向非常缓慢,直到它从传感器出来。

我的所有通讯都在SerialPort DataReceived事件中。我可以等待相关消息然后发送第二条消息的最佳方式是什么?目前我只是使用bool类型的属性,我在初始化之前将其设置为true,然后在我的事件处理程序中,如果我收到消息告诉我电机已经停止并且bool为真,我设置了bool为false并发送第二条消息。虽然这有效,但我认为可以使用async和等待?而这一般可能会更有效一点吗?或者我可以采取哪种方法更好? 任何反馈/指导将不胜感激!

2 个答案:

答案 0 :(得分:1)

在我看来,async-await的优点不在于它让你的调用者保持响应,而是你的代码看起来更容易,就好像它不是async-await一样。

使用Tasks和ContinueWith语句,或使用Backgroundworker或其他方法创建线程,也可以保持调用者响应。但是如果你使用异步等待,你不必记住你的进度状态,你现在可以通过设置布尔值来做。

您的代码如下所示:

public Task InitializeAsync(...)
{
    await Send1stMessageAsync();
    await Send2ndMessageAsync();
}

In this article Eric Lippert explained async-await using a kitchen metaphor。会发生什么事情,你的线程将尽一切努力发送第一条消息,直到它不再做任何事情,但等待回复。然后控制给不等待的第一个呼叫者。如果您没有等待,那就是您,例如,如果您有以下代码:

public Task InitializeAsync(...)
{
    var task1stMessage = Send1stMessageAsync();
    // this thread will do everything inside Send1stMessageAsync until it sees an await.
    // it then returns control to this function until there is an await here:
    DoSomeThingElse();
    // after a while you don't have anything else to do, 
    // so you wait until your first messages has been sent
    // and the reply received:
    await task1stMessage;
    // control is given back to your caller who might have something
    // useful to do  until he awaits and control is given to his caller etc.
    // when the await inside Send1stMessageAync is completed, the next statements inside
    // Send1stMessageAsync are executed until the next await, or until the function completes.

    var task2ndMessage = Send2ndMessageAsync();
    DoSomethingUseful();
    await task2ndMessage;
}

您写道,您使用事件通知您的线程已收到数据。尽管使Send1stMessageAsync成为异步函数并不困难,但您不必重新发明轮子。考虑使用像SerialPortStream这样的nuget包来获取发送消息并等待回复的异步函数。

答案 1 :(得分:0)

我正在等待事情发生,你没有事件处理程序,你可以使用async / await模式

async Task WaitForCompletion()
{
    await Task.Run(()=>
    {
        while(!theBoolVar)
            Thread.Sleep(1000);
    });
}

然后只需在您的代码中使用

await WaitForCompletion();