如果在任务返回函数中调用 Task.Result 时,调用线程是否会被阻止



我尽量不要在我的代码中创建冗余的Task对象,我编写Task返回函数,而不是在可能的情况下async Task函数。

当需要保存async函数返回的值时,我被迫使函数返回async Task并使用await调用函数。

例:

async Task SomeWorkAsync()
{
   someGlobalVariable = await AnotherWorkAsync();
}

我写的:

Task SomeWorkAsync()
{
   var task = AnotherWorkAsync();
   someGlobalVariable = task.Result;
   return task;
}

但我担心它会像同步代码一样阻止调用线程。

await SomeWorkAsync(); //main thread block

有没有另一种方法可以在示例中重写代码,而无需像关键字那样用新Task包装整个函数async

我尽量不在我的代码中创建冗余的 Task 对象,并在可能的情况下编写 Task 返回函数而不是异步 Task 函数。

这并不常见,也不是使用 TPL 的预期方式。

这是错误的:

Task SomeWorkAsync()
{
   var task = AnotherWorkAsync();
   someGlobalVariable = task.Result;
   return task;
}

你应该使用

async Task<T> SomeWorkAsync()
{
   someGlobalVariable = await AnotherWorkAsync();
   return someGlobalVariable;
}

只有在严格的情况下,您才应该使用.Result来获得Task的结果。

回答您的问题:

  1. 是的,调用.Result会阻塞您的线程。
  2. 请参阅我的评论,了解为什么我认为最好使用 await 而不是返回任务:https://stackoverflow.com/a/54211382/918058

如果你想给自己保存一个状态机,只需调用

public Task SomeWorkAsync()
{
   ...
   return AnotherWorkAsync();
}

不要调用Result,只需在方法定义中不带 async 关键字返回任务即可

简而言之,你只是在返回一个任务,可以等待更高的任务。

更新

的,如果另一个工作异步是异步任务,这可以解决问题,但在我的工作中 它是异步Task<T>的情况

public Task<MyAwesomeType> SomeWorkAsync()
{
   ...
   return AnotherWorkAsync();
}

更新 2

这仍然不是我的意思。将调用 SomeWorkAsync 的类 对私有变量 someGlobalVariable 一无所知。是的 需要获取值并在其中设置此变量

public async Task SomeWorkAsync()
{
   someGlobalVariable = await AnotherWorkAsync();
}

如果您需要异步方法的结果,则必须await它。

尽量不要混合同步代码和async await模式,这是你用Result做的,你会导致死锁......就让async传播

最新更新