【问题标题】:How can I exit a blocking enumeration in .net?如何退出 .net 中的阻塞枚举?
【发布时间】:2016-05-21 05:18:21
【问题描述】:

我使用一个库,该库将集合公开为 foreach,类似于 BlockingCollection 所做的那样,我的枚举器将等待直到提供下一个项目。

foreach(var item in items)
{
     ...
}

我的消费者将在 foreach 上等待,直到提供下一个项目。它在准备好之前不会进入块。这很好,但我希望能够在某些条件下有意停止枚举,即使我目前正在等待。

我不是在询问街区内的break。当我在块中时退出循环是微不足道的。我想“取消”来自不同线程的枚举。

【问题讨论】:

  • 可能是也可能不是stackoverflow.com/q/23295119/11683的副本
  • 我认为这将有助于澄清“停止枚举”的含义。由于代码已停止,阻塞下一项,我只能假设您正在谈论从不同线程取消线程的阻塞枚举。还是你有别的想法?
  • 既然您写的是您使用该库,我假设您无法控制代码中items 部分的实现。在那种情况下,我认为没有优雅的选择。除了添加另一个间接层,您可以将地毯拉出下面,这在最佳情况下会很笨重 - 或者如果您开始终止线程,则完全危险 - 您的选择非常有限。
  • 也许你可以使用响应式扩展。它将在内部使用调度程序,因此不需要实现。如果您不再关心下一个结果,只需处理订阅者即可。
  • @FrankJ 你说得对,我不知道。当然,我可以直接终止消费过程,但这对我来说似乎相当不雅。

标签: c# .net blocking


【解决方案1】:

它并不漂亮,但您可以将其包装在 BackgroundWorker 或其他线程技术中。

我不知道您的 BlockingCollection 是什么,但为了下面的代码,我假设它由 BlockingItem 集合 组成。

private bool _someExternalFlag;

private void Test(BlockingCollection items)
{
    _someExternalFlag = false;
    using (var worker = new BackgroundWorker())
    {
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        worker.DoWork += delegate
        {
            var index = 0;
            foreach (var item in items)
            {
                if (worker.CancellationPending)
                {
                    break;
                }
                index++;
                // ... process your item here or by passing it to the main thread
                worker.ReportProgress(index, item);
            }
        };
        worker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e)
        {
            if (_someExternalFlag)
            {
                worker.CancelAsync();
            }
            else
            {
                var item = e.UserState as BlockingItem;
                // use item if you need it
            }
        };
        worker.RunWorkerAsync();
    }
}

BackgroundWorker 的 DoWork 方法在等待下一个 BlockingItem 释放时不会占用任何 CPU 资源。

我定义的变量_someExternalFlag 可以是用户单击取消按钮时设置的任何内容,也可以是表单关闭时设置的任何内容。

【讨论】:

    猜你喜欢
    • 2012-01-25
    • 1970-01-01
    • 2017-07-15
    • 2016-12-20
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2015-10-23
    相关资源
    最近更新 更多