立即停止Parallel.ForEach [英] stop Parallel.ForEach immediately

查看:504
本文介绍了立即停止Parallel.ForEach的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为每个循环停止并行时遇到问题.

I have a problem stopping a Parallel for each loop.

我正在遍历从表中检索到的大约40.000个DataRows,当我的结果集中有100个项目时,我需要立即停止循环.问题是,当我在ParallelLoopState上触发Stop方法时,迭代不会立即停止,从而导致我的结果集中不一致(对很少或对很多项目).

I am iterating over a set of about 40.000 DataRows retrieved from a table, and I need to stop my loop immediately when I have 100 items in my resultset. The problem is that when I trigger the Stop method on the ParallelLoopState, the iteration is not stopped immediately, causing inconsistency in my resultset ( either to few or to many items).

有没有办法确保我一停就杀死所有线程?

Is there no way to make sure, that I kill all threads, as soon as I hit stop?

  List<DataRow> rows = new List<DataRow>(dataTable.Select());
  ConcurrentDictionary<string, object> resultSet = new ConcurrentDictionary<string, object>();

  rows.EachParallel(delegate (DataRow row, ParallelLoopState state)
  {
    if (!state.IsStopped)
    {
      using (SqlConnection sqlConnection = new SqlConnection(Global.ConnStr))
      {
        sqlConnection.Open();

        //{
        // Do some processing.......
        //}       

        var sourceKey = "key retrieved from processing";
        if (!resultSet.ContainsKey(sourceKey))
        {
          object myCustomObj = new object();

          resultSet.AddOrUpdate(
          sourceKey,
          myCustomObj,
          (key, oldValue) => myCustomObj);
        }

        if (resultSet.Values.Count == 100)
          state.Stop();
      }
    }
  });

推荐答案

The documentation page of ParallelLoopState.Stop explains that calling Stop() will prevent new iterations from starting. It won't abort any existing iterations.

Stop()还将设置true的="noreferrer"> IsStopped 属性.长时间运行的迭代可以检查IsStopped的值,并在需要时过早退出.

Stop() also sets the IsStopped property to true. Long running iterations can check the value of IsStopped and exit prematurely if required.

这被称为协作取消,它比放弃线程好得多.中止线程是昂贵的,并且使清理变得困难.想象一下,如果仅在您想要提交工作时抛出ThreadAbort异常,将会发生什么情况.

This is called cooperative cancellation which is far better than aborting threads. Aborting a thread is expensive and makes cleanup difficult. Imagine what would happen if a ThreadAbort exception was thrown just when you wanted to commit your work.

另一方面,合作取消允许任务在必要时提交或中止事务,关闭连接,清理其他状态和文件等后正常退出.

Cooperative cancellation on the other hand allows a task to exit gracefully after commiting or aborting transactions as necessary, closing connections, cleaning up other state and files etc.

此外,Parallel使用任务而不是线程来处理数据块.这些线程之一是启动并行操作的原始线程.中止不仅浪费线程池线程,还会杀死主线程.

Furthermore, Parallel uses tasks, not threads, to process chunks of data. One of those threads is the original thread that started the parallel operation. Aborting wouldn't just waste threadpool threads, it would also kill the main thread.

这也不是 一个错误-Parallel旨在解决数据并行性问题,而不是异步执行.在这种情况下,人们希望系统使用尽可能多的任务来处理数据,并在处理完成后继续执行.

This is not a bug either - Parallel is meant to solve data parallelism problems, not asynchronous execution. In this scenario, one wants the system to use as many tasks as appropriate to process the data and continue once that processing is complete. 

这篇关于立即停止Parallel.ForEach的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆