gpt4 book ai didi

c# - 使用 TaskCompletionSource 与 BufferBlock 包装事件

转载 作者:太空狗 更新时间:2023-10-30 01:03:07 24 4
gpt4 key购买 nike

Lucian 在这里讨论了一种模式 ( Tip 3: Wrap events up in Task-returning APIs and await them )。

我正在尝试在一个经常调用的方法上实现它,该方法看起来类似于下面的人为代码:

public Task BlackBoxAsync() 
{
var tcs = new TaskCompletionSource<Object>(); // new'ed up every call
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
DoSomethingStuff();
tcs.SetResult(null);
}
catch(Exception exc) { tcs.SetException(exc); }
});
return tcs.Task;
}

我担心性能,当TaskCompletionSource每次调用都会更新(假设我每 100 毫秒调用一次此方法)。

我当时正在考虑使用 BufferBlock<T>相反,认为它不会在每次通话时都更新。所以它看起来像:

private readonly BufferBlock<object> signalDone; // dummy class-level variable, new'ed up once in CTOR

public Task BlackBoxAsync()
{

ThreadPool.QueueUserWorkItem(_ =>
{
try
{
DoSomethingStuff();
signalDone.Post(null);
}
catch(Exception exc) { }
});
return signalDone.ReceiveAsync();
}

调用对象会这样调用它:

for (var i=0; i<10000; i++) {
await BlackBoxAsync().ConfigureAwait(false);
}

有人对使用 BufferBlock<T> 有任何想法吗?相反?

最佳答案

无论您采用何种解决方案,如果您想在每次调用此方法时都await 一个任务,那么创建一个新的Task 是不可避免的,因为任务是不可重复使用。最简单的方法是使用 TaskCompletionSource

因此,在我看来,第一个选项优于使用 BufferBlock(不出所料,creates a new TaskCompletionSource on ReceiveAsync)


更重要的是,您的代码似乎只是将工作卸载到 ThreadPool 并返回代表该工作的任务。为什么不使用简单的 Task.Run

public Task BlackBoxAsync() 
{
return Task.Run(() => DoSomethingStuff());
}

关于c# - 使用 TaskCompletionSource 与 BufferBlock<T> 包装事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30694356/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com