[英]Calling Async Method from Sync Method
I see a lot of questions about calling asyc methods from sync ones, like here: How to call asynchronous method from synchronous method in C#?我看到很多关于从同步方法调用异步方法的问题,例如: How to call asynchronous method from synchronous method in C#?
I understand the solutions however, experimentally, I am seeing that I don't need to add a .Wait()
or Task.Run(async () => await MyAsyncMethod())
for it to run synchronously.我理解解决方案,但是,通过实验,我发现我不需要添加Task.Run(async () => await MyAsyncMethod())
.Wait()
或Task.Run(async () => await MyAsyncMethod())
让它同步运行。 I have a get method that pulls information from a DB.我有一个从数据库中提取信息的 get 方法。
My code is below and when I run, it waits at var task = GetItemAsync()
and I get the correct result from the DB.我的代码在下面,当我运行时,它等待var task = GetItemAsync()
并且我从数据库中获得正确的结果。 I find it hard to believe that the DB call could come back before the code would move on which seems to imply that it ran synchronously.我发现很难相信 DB 调用会在代码继续运行之前返回,这似乎意味着它是同步运行的。 Am I missing something?我错过了什么吗?
public object GetItem()
{
var task = GetItemAsync();
var result = task.Result;
return result
}
See The docs on Task<>.Result请参阅Task<>.Result 上的文档
System.Threading.Tasks.Task.Result is a blocking call that waits until the task finishes. System.Threading.Tasks.Task.Result 是等待任务完成的阻塞调用。 So it has a built in wait call essentially.所以它本质上有一个内置的等待调用。
In the remarks section of that microsoft doc:在该微软文档的备注部分:
Accessing the property's get accessor blocks the calling thread until the asynchronous operation is complete;访问属性的 get 访问器会阻塞调用线程,直到异步操作完成; it is equivalent to calling the Wait method.相当于调用了Wait方法。
It's unfortunate that Microsoft did not reflect this in the name of the accessor because it's an extremely critical side effect of this accessor.遗憾的是,微软并没有在访问器的名称中体现这一点,因为这是访问器的一个极其关键的副作用。
The only right way to call awaitable(method which returns Task
) method is to await
it.调用 awaitable(method which returns Task
) 方法的唯一正确方法是await
它。 But you can await
only within the method which returns Task
.但是您只能在返回Task
的方法中await
。 In legacy code it happens you cannot change the method signature because you have too many reference and you need to basically refactor entire code base.在遗留代码中,您无法更改方法签名,因为您有太多引用,并且基本上需要重构整个代码库。 So you have these options:所以你有这些选择:
.Result
.Wait()
.GetAwaiter().GetResult()
Neither of those are good.这两个都不好。 All of them are going to block the thread
.所有这些都会block the thread
。 But if you cannot change the method signature to await
the execution, I would pick the last option - GetAwaiter().GetResult()
becasue it will not wrap the exception into AggregateException
但是,如果您无法更改方法签名以await
执行,我会选择最后一个选项 - GetAwaiter().GetResult()
因为它不会将异常包装到AggregateException
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.