【发布时间】:2013-12-19 14:34:44
【问题描述】:
我真的很喜欢使用 MVVM 和 async/await,所以自然而然地,我将一个项目组合在一起进行了一个新的开发 (MVVM),它通过串行方式与设备通信以工作并且 UI 具有响应性。我的驱动程序类是同步调用,它通过串行方式与设备通信,并且可能需要时间(尽管通常不会),具体取决于返回的数据量、是否获得适当的返回或驱动程序是否应该继续等待几秒钟看看是否有适当的回报,等等。
无论如何,我最终做的是将通信包装在 await Task.Run(()=>{});包装。这样,从我的 UI 角度来看,当用户单击按钮时,它会神奇地被抛出到线程池中,并且我的 UI 在处理任务时保持响应。
下面的实现不正确吗?由于我通过串行通信,我的工作在技术上不是 I/O 绑定工作而不是 CPU 绑定工作(据我所读,Task.Run 应该仅用于 CPU 绑定工作)?通过执行以下操作在我的视图模型中调用以下方法:
var returnVal = await _objName.InitAsync();
然后是 Task.Run 调用....
public async Task<bool> InitAsync()
{
bool returnVal = false;
await Task.Run(() =>
{
System.Threading.Thread.Sleep(COMMAND_DELAY_MILLISECONDS);
returnVal = _obj.InitiateProvision();
});
return returnVal;
}
bool 返回值只是说明命令是否成功。代码工作得很好,因为我已经测试了大约一个月,没有任何问题,但我不确定它是否是最好的......有没有“更好”的方法来做到这一点,同时仍然能够维护异步操作?任何指导表示赞赏!
【问题讨论】:
-
打电话给
InitiateProvision之前睡觉有什么意义?InitiateProvision也很慢吗? -
只是为了在发送命令之前添加一个短暂的延迟,我有大约 3 个命令我像这样按顺序调用,所以我添加了这个以在两次调用之间留出一些时间。我不确定这是否是最好的......使用串行端口对我来说相当新。
-
您可以从 Task.Run 返回 _obj.InitiateProvision 的返回值,从而避免捕获 returnVal 局部变量,从而避免创建类型和实例化。
标签: c# mvvm serial-port task-parallel-library async-await