是否有可能确定一个方法是否返回Task,如果返回则等待它

本文关键字:返回 是否 Task 如果 等待 方法 一个 有可能 | 更新日期: 2023-09-27 18:17:17

我的目标是将任何具有返回类型的函数传递给我的Execute方法,并序列化和存储其结果。下面是我试图做的一个粗略的想法,显然不会编译,但希望它能让你明白这个想法。我想我也应该能够递归地处理嵌套任务。想法吗?

public static TResult Execute<TResult>(Func<TResult> method)
        where TResult : class
    {
        var result = method();
        if(result is Task)
        {
            var taskResult = await result;
            StoreResult(taskResult);
        }
        else
        {
            StoreResult(result);
        }
    }

是否有可能确定一个方法是否返回Task,如果返回则等待它

这里有一个人为的例子,说明如何做到这一点。

我怀疑这种模式是否明智。我更喜欢总是返回一个任务,即使任务并不总是需要的。Task.FromResult()的开销通常可以忽略不计。
public async Task<T> Foo<T>()
{
    var mightBeATask = Bar<T>();
    var task = mightBeATask as Task<T>;
    if( task != null )
    {
        return await task;
    }
    return (T)mightBeATask;
}
private object Bar<T>()
{
    return Task.FromResult( default( T ) );
}

我同意Lee的评论,为Func<Task<TResult>>单独超载是正确的解决方案。

但是如果你真的想用一个重载来做这件事,你可以使用反射和dynamic来做这件事:

public async static Task Execute<TResult>(Func<TResult> method) where TResult : class
{
    var result = method();
    if (typeof(TResult).IsGenericType
        && typeof(TResult).GetGenericTypeDefinition() == typeof(Task<>))
    {
        var taskResult = await (dynamic)result;
        StoreResult(taskResult);
    }
    else
    {
        StoreResult(result);
    }
}