Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 914
jokeefe Avatar asked Feb 05 '13 15:02

jokeefe


2 Answers

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.

like image 163
Jon Skeet Avatar answered Oct 14 '22 11:10

Jon Skeet


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

like image 44
Stephen Cleary Avatar answered Oct 14 '22 11:10

Stephen Cleary