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

C#ReflectionWindows RuntimeAsync Await

C# Problem Overview


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

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.

How do I add await functionality to this?

C# Solutions


Solution 1 - C#

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:

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 try to 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.

Solution 2 - C#

Invoke should return an object convertible to Task. Just await that.

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>.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjokeefeView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Stephen ClearyView Answer on Stackoverflow