在不知道 T 类型的情况下获取 Task<T> 的结果

mad*_*ang 7 .net c# task-parallel-library

我正在开发一个 C# 系统,一个类有一个返回System.Threading.Tasks.Task对象的函数,并且有一个属性System.TypeReturnType。

当 ReturnType 为 null 时,我知道该方法返回一个 Task 对象。但遗憾的是,没有办法知道实现该接口的类是否会返回 or ,Task<ReturnType>Task<object>我需要获取此方法的结果。我认为最简单的方法是将 转换Task<T>Task<object>以便我可以获得结果并使用 ReturnType 中的 Type 值处理它。

在不知道 T 类型的情况下如何将 a 转换Task<T>为?Task<object>

public interface ITaskFactory
{

    ReadOnlyCollection<ParameterInfo> ParametersInfo { get; }

    Type ReturnType { get; }

    Task CreateTask (params object[] args);

}
Run Code Online (Sandbox Code Playgroud)

Task我需要获取我通过调用收到的返回的结果CreateTask()

请参阅: http: //dotnetfiddle.net/Bqwz0I

web*_*ake 6

我已经尝试了很多东西,唯一对我有用的就是使用反射。我还添加了检测没有值的任务并引发异常的代码。

using System;
using System.Threading.Tasks;
using System.Reflection;

public class Program
{
    private static async Task<object> Convert(Task task)
    {
        await task;
        var voidTaskType = typeof (Task<>).MakeGenericType(Type.GetType("System.Threading.Tasks.VoidTaskResult"));
        if (voidTaskType.IsAssignableFrom(task.GetType()))
            throw new InvalidOperationException("Task does not have a return value (" + task.GetType().ToString() + ")");
        var property = task.GetType().GetProperty("Result", BindingFlags.Public | BindingFlags.Instance);
        if (property == null)
            throw new InvalidOperationException("Task does not have a return value (" + task.GetType().ToString() + ")");
        return property.GetValue(task);
    }

    public static async Task Main()
    {
        Console.WriteLine("Start");
        Task i = CreateTask();
        Task<object> o = Convert(i);
        Console.WriteLine("value: {0}", await o);
        Console.WriteLine("value2: {0}", await Convert(Task.FromResult<int>(123)));

        //Test for tasks without return values
        try
        {
            Console.WriteLine("value3: {0}", await Convert(Task.CompletedTask));
        }
        catch (Exception ex)
        {
            Console.WriteLine("value3: EX {0}", ex.Message);
        }

        //Test for tasks without return values
        try
        {
            Console.WriteLine("value4: {0}", await Convert(Test4()));
        }
        catch (Exception ex)
        {
            Console.WriteLine("value4: EX {0}", ex.Message);
        }
        Console.WriteLine("Done");
    }


    private static Task CreateTask()
    {
        return Task.FromResult("Some result");
    }

    public static async Task Test4()
    {
        await Task.CompletedTask;
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)


aba*_*hev -2

Task<T> 不是协变的(与它不同IEnumerable<T>,请参阅其定义,注意out 关键字),因此您只能先等待它,然后再转换:

async Task<object> Do<T>(Task<T> task)
{
   // this won't compile: Cannot implicitly convert type 'Task<T>' to 'Task<object>'
   // return task;

    object result = await task;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • `Task&lt;T&gt;` 不能是协变的,只有接口和委托可以。 (2认同)