我真的很喜欢使用MVVM和async / await,所以很自然地,我将一个项目组合在一起进行新的开发(MVVM),它通过串口与设备进行通信,并且UI能够响应。我的驱动程序类是同步调用,它通过串行与设备通信,并且可能需要时间(尽管通常不会),具体取决于返回的数据量,是否获得适当的返回或驱动程序是否应该继续等待几秒钟看看是否有适当的回报等等。
无论如何,我最终做的是将通信包装在await Task.Run(()=> {})中;包装。这样,从我的UI角度来看,当用户点击按钮时,神奇地它会被抛出线程池,我的UI在处理任务时保持响应。
以下实施不正确吗?因为我通过Serial进行通信,所以技术上不是我的工作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返回值只是说明命令是否成功。代码工作得很好,因为我已经测试了大约一个月现在没有问题,但我不确定它是否最好......有没有“更好”的方法来做到这一点,同时仍然能够维护异步操作?任何指导表示赞赏!
答案 0 :(得分:1)
如果您正在使用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线程中。