【发布时间】:2015-12-17 11:46:51
【问题描述】:
我有一个高吞吐量的队列安排,我接收 Func<Task> 并希望将其投影到 Func<Task<System.Reactive.Unit>> 以很好地适应下游 Rx 系统。
由于Unit.Default 是唯一的价值,感觉这应该很容易,但我希望它尽可能高效。我希望以正确的方式通过原始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 的开销 为什么?您是否测试过这段代码并发现编译器生成的状态机结构是最重要的开销?
-
@YuvalItzchakov 谢谢 - 是的,我已经在一个紧凑的循环中对其进行了测试,发现使用
async/await与ExecuteSynchronouslyContinueWith相比,它慢了大约 46% -
或许您可以与我们分享您的测量代码和性能结果。
-
我的基准测试似乎很差,并且正在草率下结论 - 我发现了一个问题,现在看到了更接近的结果。
-
我建议使用BenchmarkDotNet,它会为您完成所有繁重的工作,而您只需编写测试。
标签: c# .net parallel-processing task-parallel-library system.reactive