c# - 将 Task 转换为 Task<Unit> 的最有效方法?

标签 c# .net parallel-processing task-parallel-library system.reactive

我有一个高吞吐量的队列安排,我接受了一个 Func<Task>并希望将其转换到 Func<Task<System.Reactive.Unit>>很好地适应下游 Rx 系统。

Unit.Default是唯一的值(value),感觉这应该很容易,但我希望它尽可能高效。我希望通过原始 Task 的所有异常以正确的方式。

我目前的做法是:

public Task<Unit> QueueTaskRx(Func<Task> task)
{
    Func<Task<Unit>> f = async () =>
    {
        await task();
        return Unit.Default;
    };

    return QueueTask(f);
}

但我担心 async/await 的开销

也许另一种更有效的方法是:

public Task<Unit> QueueTaskRx(Func<Task> task)
{
    Func<Task<Unit>> f = () => task().ContinueWith(_ =>
    {
        // What other cases do I need to consider here??
        if (_.IsFaulted && _.Exception != null)
            throw _.Exception.InnerException;

        return Unit.Default;
    }, TaskContinuationOptions.ExecuteSynchronously);

    return QueueTask(f);
}

但这并不安全,而且更复杂,分支等

有没有人有更好的方法?

最佳答案

我会使用async/await,同时添加一个ConfigureAwait(false)

可以使用 ContinueWith 来完成它,但这只会为您节省一些非常少的时间(比如单个按位标志检查和单个引用副本)。这将花费很多复杂性:

  • ContinueWith 应始终指定一个 TaskScheduler
  • 除了异常之外,您还应该处理取消,因为 Task 会专门处理取消。

对于其他陷阱,请参阅我的 Tour of Task博客系列(遗憾的是仍然不完整),我在其中尝试列举使用“旧”API 可能导致的所有问题(例如,ContinueWith)。

关于c# - 将 Task 转换为 Task<Unit> 的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34333833/

相关文章:

c# - .net 中的 PNG 压缩

c# - Xamarin.form setpage 第二次不起作用

C#:从txt文件中读取数据

.net - 如何在 .NET 中将查询字符串解析为 NameValueCollection

.net - .NET 中的 User32 API 调用

c - MPI 发送接收

c++ - openmpi mpmd 获取通信大小

c# - Azure 自定义视觉 API 返回 JPG 图像 url 不受支持的媒体类型

c# - Task.Delay(0) 和 Task.FromResult(0) 有替代方案吗?

c++ - 如果两个数据之间的不变量必须在所有线程上保持不变,它是否会强制对这些数据的读/写处于临界区?