it-swarm.com.ru

Как дождаться асинхронного частного метода, вызванного с помощью отражения в WinRT?

Я пишу модульные тесты для приложения WinRT, и я могу вызывать неасинхронные частные методы, используя это:

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

Однако, если рассматриваемый закрытый метод - async, код продолжит выполнение, не дожидаясь его завершения.

Как добавить к этому функциональность await?

56
jokeefe

Ну, вам нужно использовать значение, возвращаемое методом. Вы знаете тип? Например, если это всегда Task, вы можете использовать:

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

Если вы не знаете тип возвращаемого значения, но знаете, что он будет ожидаемым, вы можете использовать динамическую типизацию:

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

Я бы попытался чтобы избежать необходимости вызывать закрытый метод путем отражения в ваших модульных тестах в первую очередь. Можете ли вы проверить это косвенно через публичный (или внутренний) API? Это вообще предпочтительнее.

95
Jon Skeet

Invoke должен возвращать объект, конвертируемый в Task. Просто await это.

Если ваш закрытый метод возвращает void, то вам понадобится пользовательское SynchronizationContext, которое является грязным. Лучше, чтобы ваши методы возвращали Task/Task<T>.

7
Stephen Cleary