【问题标题】:How to Terminate Threads that started within foreach loop in C#如何终止在 C# 中的 foreach 循环中启动的线程
【发布时间】:2012-05-17 11:05:02
【问题描述】:

我为我的 Windows 服务中的每个循环启动了多个线程。我没有提到这些线程的任何名称。我怎样才能终止这些线程。 我使用下面的代码来创建线程。

 new Thread(() =>
            {
                foreach (MyClass detail in MyclassList)
                {
                    DoWork(detail);
                }

            }).Start();

通过启动这些线程,我为每个细节创建了一个调度任务。我可以在调度完成后处理这个线程吗?如何?

【问题讨论】:

  • 终止什么?由谁?为什么是“线程”?您正在创建一个线程,它将按顺序处理每个任务,但与“主”线程并行
  • 你的意思是在执行期间杀死线程还是仅仅加入它们?
  • DoWork 任务完成后我想中止创建的线程
  • @Satheesh 如果您在DoWork 之后中止,您将只处理列表中的一项。更好的方法是使用 .Take(1) 或类似的

标签: c# windows multithreading service


【解决方案1】:

强制终止线程绝不是个好主意。您真正应该做的是在循环中放置一些经过适当设计的“我应该继续”检查,您可以在外部将其设置为“否”。 如何 这样做更多地取决于上下文...例如:

        int shouldExit = 0;
        new Thread(() =>
        {
            foreach (MyClass detail in MyclassList)
            {
                if(Thread.VolatileRead(ref shouldExit) != 0) break;
                DoWork(detail);
            }
        }).Start();
        ...
        // to terminate loop:
        Thread.VolatileWrite(ref shouldExit, 1);

然而,有无数种方法可以整理出线程安全的退出测试;唯一有点棘手的事情是保持某种上下文以访问被检查的东西。

【讨论】:

  • 有点困惑。通过调用 new Thread() 会创建一个线程吗?。上面的代码会终止这个线程还是终止循环。我的问题是在 DoWork() 完成之后中止或终止线程。
  • @Satheesh 线程在到达被要求执行的方法的末尾时终止自身。因此:如果你想终止:只需 break; 退出循环。我的回答假设您想从循环的 outside 请求 - 如果您想从循环的 inside 终止,它甚至更简单 - 只需 break; 循环当你想退出时。
【解决方案2】:

首先,我会使用Task 类而不是直接创建一个新线程。然后,我会使用内置的 TPL 取消机制。这是它的样子。

var cts = new CancellationTokenSource();
var token = cts.Token;

var task = Task.Factory.StartNew(
  () =>
  {
    foreach (MyClass detail in MyclassList)
    {
      ct.ThrowIfCancellationRequested();
      DoWork(detail);
    }
  }, cts.Token); 

// Do other stuff here.

cts.Cancel(); // Request cancellation.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-14
    • 2021-06-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多