Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / MulticastDelegate и Task / 5 сообщений из 5, страница 1 из 1
25.10.2021, 22:29
    #40106875
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MulticastDelegate и Task
Есть некий супер-пупер метод, фишку которого можно свести к этим строкам:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
public static object ReturnCall<T>(T func, object[] values) where T : MulticastDelegate
    => func.Method.Invoke(func.Target, values);

//вызов: 
var xyz = ReturnCall<Func<int, string, long>>(SomeFunc, values)

//что вызывается:
long SomeFunc(int x, string y) {}
        


Не спрашивайте, почему такой непрямой вызов - религия позволяет только так.

А как сделать await всей этой пирожни, если вызывается async?
Код: c#
1.
2.
3.
var xyz = ReturnCall<Func<int, string, Task<long>>>(SomeFunc, values)

async Task<long> SomeFunc(int x, string y) {}
...
Рейтинг: 0 / 0
26.10.2021, 07:29
    #40106927
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MulticastDelegate и Task
Как-то вот так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
public class Program
{
  static async Task Main()
  {
    var result = (int)await ReturnCallAsync<Func<string, Task<int>>>(Foo, new object[]{"0123456789"});
    Console.WriteLine(result);
    await CallAsync<Func<IEnumerable<string>, Task>>(Bar, new object[]{new[] {"foo", "bar", "zot"}});
  }

  static async Task<object> ReturnCallAsync<T>(T func, object[] values) where T : MulticastDelegate
  {
    var returnType = func.Method.ReturnType;
    if (!(typeof(Task).IsAssignableFrom(returnType) && returnType.IsGenericType))
      throw new InvalidOperationException();
    dynamic awaiter = func.Method.Invoke(func.Target, values);
    await awaiter;
    return awaiter.GetAwaiter().GetResult();
  }

  static async Task CallAsync<T>(T action, object[] values) where T : MulticastDelegate
  {
    var returnType = action.Method.ReturnType;
    if (!(typeof(Task).IsAssignableFrom(returnType) && !returnType.IsGenericType))
      throw new InvalidOperationException();
    dynamic awaiter = action.Method.Invoke(action.Target, values);
    await awaiter;
  }

  static async Task<int> Foo(string argument)
  {
    await Task.Yield();
    return argument?.Length ?? -1;
  }

  static async Task Bar(IEnumerable<string> arguments)
  {
    await Task.Yield();
    Console.WriteLine(arguments?.Any() ?? false ? arguments.Aggregate((a,b)=>$"{a},{b}") : "sequence is empty");
  }
}


Если использование dynamic не устраивает - результат Invoke приводить к Task (Task<TResult> унаследован от просто Task), ему делать await, и если делегат возвращает Task<TResult>, то рефлекшеном получать значение Task<TResult>>.Result.
...
Рейтинг: 0 / 0
26.10.2021, 12:18
    #40107011
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MulticastDelegate и Task
Спасибо!
...
Рейтинг: 0 / 0
29.10.2021, 04:46
    #40107919
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MulticastDelegate и Task
Antonariy,

шож вы там такое делаете, стесняюсь спросить )
...
Рейтинг: 0 / 0
29.10.2021, 08:40
    #40107933
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MulticastDelegate и Task
hVostt
Antonariy,

шож вы там такое делаете, стесняюсь спросить )


пусть делает, не трогайте его (ц)
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / MulticastDelegate и Task / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]