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

Код: 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
MulticastDelegate и Task
    #40106927
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то вот так:
Код: 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
MulticastDelegate и Task
    #40107011
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо!
...
Рейтинг: 0 / 0
MulticastDelegate и Task
    #40107919
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

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

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


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


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