异步等待多个线程完成

时间:2018-02-21 12:10:32

标签: c# multithreading async-await synchronization countdownevent

我有一个代码块,最终由多个线程访问。我搜索了一个最新的异步机制,以便在所有线程都通过后继续执行。

目前我使用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,因为它具有异步功能,但我认为它有点矫枉过正。

评论的补充:

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);
    }

1 个答案:

答案 0 :(得分:0)

不清楚IActivity签名;但是你可以等待完成一系列任务:

class MultiAsyncTest {

    Task SomeAsync1() { return Task.Delay(1000); }

    Task SomeAsync2() { return Task.Delay(2000);}

    Task EntryPointAsync() {
        var tasks = new List<Task>();
        tasks.Add(SomeAsync1());
        tasks.Add(SomeAsync2());
        return Task.WhenAll(tasks);
    }

}

IActivity的签名是什么?它是否支持Task?或者您正在使用Thread?更多解释将有助于更明确的答案。