我真的很喜欢使用 MVVM 和 async/await,所以很自然地,我将一个项目组合在一起进行了一个新的开发 (MVVM),它通过串行方式与设备通信以工作并且 UI 响应。我的驱动程序类是同步调用,它通过串行方式与设备通信,并且可能需要时间(尽管通常不会),具体取决于返回的数据量、是否获得适当的返回或驱动程序是否应该继续等待几秒钟看看是否出现了适当的返回等。
无论如何,我最终做的是将通信包装在 await Task.Run(()=>{});包装。这样,从我的 UI 角度来看,当用户单击按钮时,它神奇地被抛出到线程池中,并且我的 UI 在处理任务时保持响应。
下面的实现不正确吗?由于我通过串行通信,我的工作在技术上不是 I/O 绑定(bind)工作而不是 CPU 绑定(bind)工作(据我所读,Task.Run 应该仅用于 CPU 绑定(bind)工作)?通过执行以下操作在我的 View 模型中调用以下方法:
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 返回值只是说明命令是否成功。代码工作得很好,因为我已经测试了大约一个月,没有任何问题,但我不确定它是否是最好的......有没有“更好”的方法来做到这一点,同时仍然能够维护异步操作?任何指导表示赞赏!
最佳答案
如果您使用 Task.Run
只是为了让您在执行命令之前有一个延迟,只需使用 delay并且不要占用线程池。
public async Task<bool> InitAsync()
{
bool returnVal = false;
await Task.Delay(COMMAND_DELAY_MILLISECONDS).ConfigureAwait(false);
returnVal = _obj.InitiateProvision();
return returnVal;
}
你说你有 3 个命令,如果它适合你的设计,你可以连续执行所有三个命令,你可以有多个
await
在一个函数中。public async Task<bool> InitAsync()
{
bool returnVal = false;
await Task.Delay(COMMAND_DELAY_MILLISECONDS).ConfigureAwait(false);
returnVal = _obj.InitiateProvision();
if(returnVal == true)
{
await Task.Delay(COMMAND_DELAY_MILLISECONDS).ConfigureAwait(false);
returnVal = _obj.CommandTwo();
}
if(returnVal == true)
{
await Task.Delay(COMMAND_DELAY_MILLISECONDS).ConfigureAwait(false);
returnVal = _obj.CommandThree();
}
return returnVal;
}
.ConfigureAwait(false)
使函数在 await
之后继续工作时不需要返回 UI 线程。并且可以使程序更快,因为它不需要在 UI 线程中等待轮到它。
关于c# - Task.Run 串行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20684379/