C#async和await关键字在使用属性getter时未按预期工作
你能简单地解释一下为什么这段代码的前两行不是并行运行的吗?我怎样才能使它并行工作 SensorLeft和SensorRight属于同一类,距离是它的公共属性,在调用其get方法时需要计算一些时间 我做错了什么?我应该将距离计算作为异步函数来进行吗C#async和await关键字在使用属性getter时未按预期工作,c#,.net,properties,async-await,getter,C#,.net,Properties,Async Await,Getter,你能简单地解释一下为什么这段代码的前两行不是并行运行的吗?我怎样才能使它并行工作 SensorLeft和SensorRight属于同一类,距离是它的公共属性,在调用其get方法时需要计算一些时间 我做错了什么?我应该将距离计算作为异步函数来进行吗 public async void GetDistance() { await Task.Run(() => LeftDistance = SensorLeft.Distance); await Task.Run(() =>
public async void GetDistance()
{
await Task.Run(() => LeftDistance = SensorLeft.Distance);
await Task.Run(() => RightDistance = SensorRight.Distance);
Distance = RightDistance < LeftDistance ? RightDistance:LeftDistance;
}
public异步void GetDistance()
{
等待任务。运行(()=>LeftDistance=SensorLeft.Distance);
等待任务。运行(()=>RightDistance=SensorRight.Distance);
距离=右距离<左距离?右距离:左距离;
}
当编译器遇到wait
关键字时,它将自动在任务计划程序中计划任务。该操作(以非阻塞方式)等待任务完成,然后继续执行代码块的其余部分
要使代码并行运行,需要将其修改为
public async Task GetDistance()
{
var leftDTask = Task.Run(() => LeftDistance = SensorLeft.Distance);
var rightDTask= Task.Run(() => RightDistance = SensorRight.Distance);
await Task.WhenAll(leftDTask,rightDTask);
Distance = RightDistance < LeftDistance ? RightDistance:LeftDistance;
}
然而,这并不是一个好的解决方案。如果您想让get距离真正异步,那么应该创建一个异步get方法,而不是将其包装到Task.Run中 当您等待第一个任务时,您正在等待它完成,然后再移动到下一行代码。首先分配任务,然后使用
Task.whalll
让它们同时运行。async void
仅适用于事件处理程序。您应该使用async Task
<代码>等待表示等待异步操作完成。是Task.Run
并行启动工作,而不是wait
。如果您希望操作并行运行,请将返回的任务存储在数组中,并使用wait Task.whall(tasks)
等待这两个任务完成。此外,除非您调用的异步方法没有IO完成端口,否则这不仅速度较慢,而且使用线程可能会导致更多性能问题。请记住,等待并不能使某些东西异步。等待检查任务是否已完成,如果未完成,则返回,以便调用者可以找到更多的工作要做。在这种情况下,方法的剩余部分将用于完成等待的任务。如果你认为等待会使事情变得不同步,那么今天就从你的头脑中清除这个错误的信念。谢谢!将其包装到Task.Run或使get async中有什么区别?顺便问一下,我可以使属性getter异步还是必须使其作为函数?属性getter不支持异步,必须使getter函数。我承认将同步操作包装到Task.Run中是进行异步操作的最快方法,但不推荐这样做。Stephen Toub MSFT在本博客中有更好的解释
public async Task GetDistance()
{
var leftDTask = Task.Run(() => SensorLeft.Distance);
var rightDTask= Task.Run(() => SensorRight.Distance);
var results= await Task.WhenAll(leftDTask,rightDTask);
Distance = Math.Min(results[0],results[1]);
}