Casting TResult in Task to System.Object

后端 未结 3 1900
误落风尘
误落风尘 2020-12-16 01:54

I am loading an assembly and calling a static method that will create a new object of type “MyClass1” (this type is specified at runtime) through reflection using MethodInfo

相关标签:
3条回答
  • 2020-12-16 02:14

    Another possibility is to write an extension method to this purpose:

        public static Task<object> Convert<T>(this Task<T> task)
        {
            TaskCompletionSource<object> res = new TaskCompletionSource<object>();
    
            return task.ContinueWith(t =>
            {
                if (t.IsCanceled)
                {
                    res.TrySetCanceled();
                }
                else if (t.IsFaulted)
                {
                    res.TrySetException(t.Exception);
                }
                else
                {
                    res.TrySetResult(t.Result);
                }
                return res.Task;
            }
            , TaskContinuationOptions.ExecuteSynchronously).Unwrap();
        }
    

    It is none-blocking solution and will preserve original state/exception of the Task.

    0 讨论(0)
  • 2020-12-16 02:15

    You cannot cast Task<T> to Task<object>, because Task<T> is not covariant (it's not contravariant, either). The simplest solution would be to use some more reflection:

    var task   = (Task) mi.Invoke (obj, null) ;
    var result = task.GetType ().GetProperty ("Result").GetValue (task) ;
    

    This is slow and inefficient, but usable if this code is not executed often. As an aside, what is the use of having an asynchronous MakeMyClass1 method if you are going to block waiting for its result?

    0 讨论(0)
  • 2020-12-16 02:18

    As an enhancement to the accepted answer, you can avoid the blocking by awaiting the Task in between:

    var task = (Task)mi.Invoke(obj, null);
    await task;
    var result = task.GetType().GetProperty("Result").GetValue(task);
    

    Of course this will be properly asynchronous only if all methods up the call stack are marked async and you're using await instead of .Result everywhere.

    0 讨论(0)
提交回复
热议问题