【问题标题】:Async wait for multiple threads to finish异步等待多个线程完成
【发布时间】: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);
    }

【问题讨论】:

标签: c# multithreading async-await synchronization countdownevent


【解决方案1】:

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?更多解释将有助于获得更具体的答案。

【讨论】:

  • 编辑了最初的帖子。但 IActivity 的实现方式如何并不重要。我只想完成这个过程,并且 CountdownEvent 在没有异步支持的情况下已经很好了。当然我可以包装一个 Task.Run ,但我猜这不是最好的解决方案。
  • 好的,我明白了。我以为你想等待IActivity 处决(虽然我没有要求执行,但要求签名;无论如何)。但我认为现在你想开始并等待// Threads processing 部分中的一些线程。正确的?为什么不在这里开始一些Tasks 并等待他们?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
相关资源
最近更新 更多