使用 async/await 或其他东西
Posted
技术标签:
【中文标题】使用 async/await 或其他东西【英文标题】:Use async/ await or something else 【发布时间】:2016-09-12 08:57:41 【问题描述】:我正在编写一个与我设计的一些控制硬件进行通信的程序。硬件正在驱动电机,我尝试用它做的第一件事是初始化电机。 硬件是通信控制的,所以我只需通过 USB 向硬件发送一条消息即可。 要初始化电机,我必须发送 2 条消息;在我发送第一个之后,它会将电机移向传感器,当它到达它时它会停止并向我发送一条消息,告诉我它已经停止,此时我向它发送另一条消息,告诉它驱动电机相反的方向非常缓慢,直到它从传感器中出来。
我所有的通讯接收都在 SerialPort
DataReceived
事件中。我可以等待相关消息然后发送第二条消息的最佳方式是什么?目前我只是使用 bool 类型的属性,在初始化之前我将其设置为 true,然后在我的事件处理程序中,如果我收到消息告诉我电机已停止并且 bool 为真,我设置 bool为假并发送第二条消息。虽然这可行,但我在想可能可以使用异步和等待?总的来说,这可能会更有效率吗?还是我可以采取另一种更好的方法?
任何反馈/指导将不胜感激!
【问题讨论】:
距离不够近,不能被称为重复,但您可能想看看我为 for a similar answer 设计的一个类,该类将对 SeralPort 的请求排队并异步等待响应。跨度> 谢谢你,非常有用!我会看看我是否可以调整和实现类似的东西,但我不能使用你提出的确切答案,因为我确实需要事件来处理消息的接收。 【参考方案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 包来获取发送消息并等待回复的异步函数。
【讨论】:
【参考方案2】:如果您正在等待某些事情发生并且您没有事件处理程序可供您使用,那么使用 async/await 模式是个好主意
async Task WaitForCompletion()
await Task.Run(()=>
while(!theBoolVar)
Thread.Sleep(1000);
);
然后就在你的代码中使用
await WaitForCompletion();
【讨论】:
以上是关于使用 async/await 或其他东西的主要内容,如果未能解决你的问题,请参考以下文章