gpt4 book ai didi

c# - 可以等待的异步计数器

转载 作者:太空狗 更新时间:2023-10-29 21:40:18 29 4
gpt4 key购买 nike

我有一个连接类,它有几个异步方法,例如 SendText、SendImage 等。

连接类有一个 Disconnect 方法,当它被调用时我必须小心,不要在所有异步方法完成执行之前开始改变类的内部状态。

我相信实现这一目标的一个好方法是简单地保持执行中的操作总数,然后当我想断开连接时,我可以简单地设置 Disconnecting = true 然后等待计数达到 0

我在想一些类似的事情

class ReferenceCounter
{
void Increment();

void Decrement();

async Task WaitForCounterToReachZero();
}

然后当异步操作开始时我可以做

refCounter.Increment();

什么时候结束

refCounter.Decrement();

在 Disconnect 方法中

disconnecting = true;
taskCancellationSource.Cancel();
await refCounter.WaitForCounterToReachZero();
Cleanup();

有这样的内置 .NET 类吗?

或者对我来说更重要的是,是否有更好的方法来做到这一点?

如果是同步代码就很简单了

lock (thisLock)
{
while (counter > 0)
Monitor.Wait(thisLock);
}

我刚刚找到了内置的 CountdownEvent 类,它做同样的事情,但它没有异步 Wait 方法,也没有任何事件,所以我不得不阻止。

最佳答案

好吧,假设你在将它设为 0 之后 不再递增,你可以这样做:

public class Latch
{
private int count = 0;
private readonly TaskCompletionSource<object> tcs =
new TaskCompletionSource<object>();

public void Increment()
{
Interlocked.Increment(ref count);
}

public void Decrement()
{
if (Interlocked.Decrement(ref count) == 0)
{
tcs.TrySetValue(null);
}
}

public Task Task { get { return tcs.Task; } }
}

然后你可以等待someLatch.Task。或者,您可以使闩锁本身可等待:

public TaskAwaiter GetAwaiter()
{
return tcs.Task.GetAwaiter();
}

您可能应该考虑如何防止“下降到 0 后计数上升”方面的问题 - 考虑您希望它做什么。 (在上面的代码中,一旦设置了 TCS 的值,进一步的等待将立即完成。)

关于c# - 可以等待的异步计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14314223/

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