TaskContinuationOptions.OnlyOnRanToCompletion)
пока у меня получилось вот так
private static Task AddContinueWith(Task origin, Type returnType, Func<object> returnProvider) {
var cont = new DynamicMethod("", returnType, new[] { typeof(Task) }, typeof(CommandWrapper).Module);
var il = cont.GetILGenerator();
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Callvirt, returnProvider.GetMethodInfo());
il.Emit(OpCodes.Ret);
var delType = typeof(Func<,,>).MakeGenericType(typeof(Task), typeof(object), returnType);
var delVar = cont.CreateDelegate(delType);
var continueWith = typeof(Task).GetMethod(
nameof(origin.ContinueWith),
BindingFlags.Instance,
null,
new Type[] { delType, typeof(TaskContinuationOptions), },
null
);
return (Task)continueWith!.Invoke(origin, new object[] { delVar, TaskContinuationOptions.OnlyOnRanToCompletion })!;
}
Так в результате верхний метод возвращает просто task, то есть значение типа returntype теряется
значение теряется для компилятора. У объекта тип должен быть Task< «returnType» >
Тогда да, я бы заюзал expression вместо ручной генерации тела, как минимум в угоду поддерживаемости
Почему там нельзя вызвать метод через create generic ?
А как скастить делегат Func<object> к Func<T> ?
Делаешь статический дженерик метод который будет делать тоже самое, потом его просто дергаешь
да, только делегат, который нужно скастить - он внешний для внутренней функции, которая передаётся в ContinueWith
Советую такое делать через MakeGenericMethod, раз уж тебе пофиг на перф. Код станет на порядок проще.
Обсуждают сегодня