web-dev-qa-db-ja.com

WinRTのリフレクションを使用して呼び出された非同期プライベートメソッドを待つ方法は?

私はWinRTアプリの単体テストを書いており、これを使用して非同期ではないプライベートメソッドを呼び出すことができます:

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

ただし、問題のプライベートメソッドがasyncの場合、コードは終了を待たずに実行を継続します。

await機能をこれに追加するにはどうすればよいですか?

58
jokeefe

さて、メソッドから返された値を使用する必要があります。タイプを知っていますか?たとえば、常にTaskである場合、次を使用できます。

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

戻り値の型はわからないが、待ち受け可能になるとわかっている場合は、動的型付けを使用できます。

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

私はtryでも、そもそもユニットテストに反映することでプライベートメソッドを呼び出さなくて済むようにします。パブリック(または内部)APIを介して間接的にテストできますか?それは一般的に望ましいことです。

100
Jon Skeet

Invokeは、Taskに変換可能なオブジェクトを返す必要があります。ただawaitそれ。

プライベートメソッドがvoidを返す場合、面倒なカスタムSynchronizationContextが必要になります。メソッドがTask/Task<T>を返すようにすることをお勧めします。

8
Stephen Cleary