如何创建一个通用的Task.ContinueWith扩展方法

时间:2015-05-22 08:08:14

标签: c# generics task-parallel-library

所以目前我有一个Task.ContinueWith扩展方法,如下所示:

public static Task ContinueWith_UsingSyncContextWorkaround(this Task task, Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler, SynchronizationContext sc)
{
    Action<Task> actionWithWorkaround = t =>
    {
        SynchronizationContext.SetSynchronizationContext(sc);
        continuationAction(t);
    };

    return task.ContinueWith(actionWithWorkaround, cancellationToken, continuationOptions, scheduler);
}

这样可以正常工作,但它不能让我访问Task的结果,所以我想创建一个通用的扩展方法。

我试过了:

public static Task<T> ContinueWith_UsingSyncContextWorkaround(this Task<T> task, Action<Task<T>> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler, SynchronizationContext sc)
{
    Action<Task<T>> actionWithWorkaround = t =>
    {
        SynchronizationContext.SetSynchronizationContext(sc);
        continuationAction(t);
    };

    return task.ContinueWith(actionWithWorkaround, cancellationToken, continuationOptions, scheduler);
}

但这不会编译因为

  

无法找到类型或命名空间名称

如何创建通用的Task.ContinueWith扩展方法?

1 个答案:

答案 0 :(得分:5)

您错过了方法名称中的T声明。此外,您Action<T>需要成为Func<Task<T>, T>

public static Task<T> ContinueWithUsingSyncContextWorkaround<T>(this Task<T> task,
                                               Func<Task<T>, T> continuationFunc, 
                                               CancellationToken cancellationToken,
                                               TaskContinuationOptions continuationOptions,
                                               TaskScheduler scheduler,
                                               SynchronizationContext sc)
{
    Func<Task<T>, T> funcWithWorkaround = t =>
    {
        SynchronizationContext.SetSynchronizationContext(sc);
        return continuationFunc(t);
    };

    return task.ContinueWith<T>(funcWithWorkaround, cancellationToken,
                                continuationOptions, scheduler);
}