C# 如何等待在 WinRT 中使用反射调用的异步私有方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14711585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:46:01  来源:igfitidea点击:

How to await an async private method invoked using reflection in WinRT?

c#reflectionwindows-runtimeasync-await

提问by jokeefe

I'm writing unit tests for a WinRT app, and I am able to invoke non-async private methods using this:

我正在为 WinRT 应用程序编写单元测试,并且可以使用以下方法调用非异步私有方法:

TheObjectClass theObject = new TheObjectClass();
Type objType = typeof(TheObjectClass);
objType.GetTypeInfo()
       .GetDeclaredMethod("ThePrivateMethod")
       .Invoke(theObject, null);

However, if the private method in question is async, the code will continue execution without waiting for it to finish.

但是,如果有问题的私有方法是async,代码将继续执行而不等待它完成。

How do I add awaitfunctionality to this?

我如何await为此添加功能?

采纳答案by Jon Skeet

Well you need to use the value returned by the method. Do you know the type? For example, if it's always a Task, you could use:

那么您需要使用该方法返回的值。你知道类型吗?例如,如果它总是 a Task,你可以使用:

await (Task) objType.GetTypeInfo()
                    .GetDeclaredMethod("ThePrivateMethod")
                    .Invoke(theObject, null);

If you don't know the return type but know it will be awaitable, you could use dynamic typing:

如果您不知道返回类型但知道它可以等待,则可以使用动态类型:

await (dynamic) objType.GetTypeInfo()
                       .GetDeclaredMethod("ThePrivateMethod")
                       .Invoke(theObject, null);

I would tryto avoid having to call a private method by reflection in your unit tests in the first place though. Can you test it indirectly via the public (or internal) API? That's generally preferable.

不过,我会尽量避免首先在单元测试中通过反射来调用私有方法。您可以通过公共(或内部)API 间接测试它吗?这通常是可取的。

回答by Stephen Cleary

Invokeshould return an object convertible to Task. Just awaitthat.

Invoke应该返回一个可转换为Task. 就是await这样。

If your private method returns void, then you'll need a custom SynchronizationContext, which is messy. It's better to have your methods return Task/Task<T>.

如果您的私有方法返回void,那么您将需要一个 custom SynchronizationContext,这很麻烦。最好让您的方法返回Task/ Task<T>