Как вызвать асинхронный метод и получить результат без использования динамики - PullRequest
0 голосов
/ 21 сентября 2018

Как вызвать асинхронный метод и получить результат без использования динамики

Я хочу вызвать асинхронный метод с отражением.Как я выяснил, есть два способа сделать это

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

или

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

Проблема в том, что если я не знаю тип возвращаемого значения, мне нужно сделать это, как вВторой примерНо моя проблема в том, что я не могу использовать динамику в своем проекте.Как я могу вызвать асинхронный метод, не зная тип возвращаемого значения и не используя динамику.

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Ожидание Task<T> через отражение будет настоящей болью.Вместо этого вы можете разделить проблему: вы уже знаете, как ждать Task, просто потом вручную получить результат:

var task = objType.GetTypeInfo()
    .GetDeclaredMethod("ThePrivateMethod")
    .Invoke(theObject, null);

await (Task)task;

var taskType = task.GetType();

if (taskType.IsGenericType && taskType.GetGenericTypeDefinition() == typeof(Task<>))
{
    var result = taskType.GetProperty("Result").GetValue(task);

    Console.WriteLine(result);
}

Похоже, что фреймворк иногда возвращает Task<VoidTaskResult> замаскированныйкак Task.Если это проблема, вы можете отфильтровать их:

var voidTaskResult = Type.GetType("System.Threading.Tasks.VoidTaskResult");


if (taskType.IsGenericType
    && taskType.GetGenericTypeDefinition() == typeof(Task<>)
    && taskType.GetGenericArguments()[0] != voidTaskResult)
{
    var result = task.GetType().GetProperty("Result").GetValue(task);

    Console.WriteLine(result);
}
0 голосов
/ 21 сентября 2018

Хотя общая задача, полученная из задачи, свойство результата существует только в определении класса задачи.Кроме того, поскольку это не интерфейс, он не может быть ковариантным, и поэтому Задача X не может быть назначена Задаче объекта.

Вам нужно будет использовать динамику или отражение, никак не обойти его.

Самый простой без использования динамического может выглядеть как

var task = (Task) objType.GetTypeInfo()
                .GetDeclaredMethod("ThePrivateMethod")
                .Invoke(theObject, null);

await task;

object result = task.GetType().GetProperty(“Result”).GetValue(task, null)
0 голосов
/ 21 сентября 2018

будет ли указывать его как объект работы?

   TheObjectClass theObject = new TheObjectClass();
    Type objType = typeof(TheObjectClass);
    object obj = objType.GetTypeInfo().GetDeclaredMethod("GetInt").Invoke(theObject, null);
    object val  = obj.GetType().GetProperty("Result").GetValue(obj);
    Type t = val.GetType();
    Console.WriteLine(t.Name);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...