【发布时间】:2018-02-21 12:10:31
【问题描述】:
我有一个最终被多个线程访问的代码块。我搜索了一个最新的异步机制,以便在所有线程都通过后继续执行。
目前我使用 CountDownEvent 执行以下操作,效果很好(没有异步支持)。
public class Watcher
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private readonly CountdownEvent _isUpdating = new CountdownEvent(1);
private readonly IActivity _activity;
public Watcher([NotNull] IActivity activity)
{
_activity = activity ?? throw new ArgumentNullException(nameof(activity));
_activity.Received += OnReceived;
}
private void OnReceived(IReadOnlyCollection<Summary> summaries)
{
_isUpdating.AddCount();
try
{
// Threads processing
}
finally
{
_isUpdating.Signal();
}
}
private void Disable()
{
_activity.Received -= OnReceived;
_isUpdating.Signal();
/* await */ _isUpdating.Wait();
}
}
我是否需要使用任何这些 AsyncCountdownEvent 实现,或者是否有任何其他内置机制?我已经考虑过使用 BufferBlock,因为它具有异步功能,但我认为这有点矫枉过正。
cmets 的补充:
IActivity 是一个 WebService 调用(但不应影响顶部的实现,反之亦然)
public async Task Start(bool alwayRetry = true, CancellationToken cancellationToken = new CancellationToken())
{
var milliseconds = ReloadSeconds * 1000;
do
{
try
{
var summaries = await PublicAPI.GetSummariesAsync(cancellationToken).ConfigureAwait(false);
OnSummariesReceived(summaries);
}
catch (Exception ex)
{
Log.Error(ex.Message);
OnErrorOccurred(ex);
}
await Task.Delay(milliseconds, cancellationToken).ConfigureAwait(false);
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
} while (alwayRetry);
}
【问题讨论】:
-
看看Task.WhenAll docs.microsoft.com/en-us/dotnet/api/…
-
我并没有真正的任务引用,只是一个可以被多个线程访问的代码块。
标签: c# multithreading async-await synchronization countdownevent