使用.Net调用异步方法并等待

81

我有一个异步方法

public Task<Car> GetCar()
{

}

我可以使用async和await调用这个方法:

 Car car = await GetCar()

如何使用 MethodInfo.Invoke 调用方法并异步等待结果。

 MethodInfo method = obj.GetMethod("GetCar");
 method.Invoke( obj, null)

3
如何在WinRT中使用反射等待异步私有方法的完成?如何等待通过反射调用的异步私有方法完成? 我试图使用 TaskCompletionSource<TResult> 来实现这一点,但是我需要知道如何从 MethodInfo.Invoke 中获取结果。 如果我尝试等待 TaskCompletionSource.Task,我会得到一个 System.ArgumentException,其中提供了以下消息:“ 无法将返回类型为“System.Threading.Tasks.Task`1 [TResult]”的对象转换为类型“System.Threading.Tasks.Task”。” 这是我的代码:private async Task AsyncMethod() { await Task.Delay(1000); return 42; } private async Task InvokeAsyncMethod() { var method = GetType().GetTypeInfo().GetDeclaredMethod(nameof(AsyncMethod)); var tcs = new TaskCompletionSource(); var task = (Task)tcs.Task; // Throws ArgumentException method.Invoke(this, null); return await task; } - Markus Palme
“异步等待” - 你是不是指的是“ContinueWith”? - Marc Gravell
1个回答

187

您可以正常调用它,然后await返回的任务:

Task<Car> result = (Task<Car>)method.Invoke(obj, null);
await result;

4
@Daniel: 不,await不会阻塞当前线程。这正是 await 的全部意义所在。它真正是非阻塞的。我有一篇异步简介另一篇博客文章,其中更详细地介绍了这个概念。 - Stephen Cleary
3
如果有帮助的话,你可以将async视为将方法转换成状态机,而每个await是状态机方法返回的(潜在)点。从这个角度来看,await只是一种非常复杂的回调语法。因此,虽然await确实会“暂停”方法直到可等待操作完成并将局部变量提升到堆上,但重要的是要注意:1)没有线程等待方法继续执行(它是回调而不是线程),2)调用栈不会被保留(回调直接执行状态机的下一部分)。 - Stephen Cleary
1
@Daniel:不,没有代理,因为await使用回调函数。当操作完成时,回调函数就是方法的继续执行。async关键字告诉编译器将方法分成块(在每个await点),然后当await暂停时,它只需将下一个方法块连接为回调函数。因此,这些都没有监视器、代理或管理器;一切都是回调函数。这也是为什么调用堆栈会丢失的原因;该块直接作为回调函数运行,而没有原始调用堆栈。 - Stephen Cleary
1
@Daniel:无论是哪种完成任务的代码,都会执行任务的后续操作。在 I/O 的情况下,这是一个线程池线程。同样,这是回调函数,回调函数只是在线程池线程上执行。 - Stephen Cleary
3
@StephenCleary,我明白了。感谢您花费这么多时间为我解释!我还意识到我有你写的并发编程的书!显然,在进行这次对话之前,我应该先把它读完 :)。 - Daniel
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接