如何中止多个线程?

may*_*sam 5 .net c# multithreading thread-abort winforms

在此代码中,button1单击两次时,它将创建2个单独的线程.只需单击一下,它就会在堆上创建一个新线程,而field将t1指向堆上的新线程.当我单击时button2,它将中止最后一个线程(t1指的是).

我如何中止其他线程?

Thread t1;
ThreadStart ts1;

private void button1_Click(object sender, EventArgs e)
{
    ts1 = new ThreadStart(myfunc);
    t1 = new Thread(ts1);
    t1.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    t1.Abort();
}
Run Code Online (Sandbox Code Playgroud)

Ani*_*Ani 7

好吧,OO的答案是将一个线程列表作为一个字段.

private readonly List<Thread> threads = new List<Thread>();
Run Code Online (Sandbox Code Playgroud)

然后将新构造的线程添加到第一个处理程序的列表中.

var thread = new Thread(myfunc);
thread.Start();
threads.Add(thread);
Run Code Online (Sandbox Code Playgroud)

然后你可以迭代第二个处理程序中的每个线程,依次中止每个线程.

foreach(var thread in threads)
   thread.Abort();
Run Code Online (Sandbox Code Playgroud)

但我认为这里最重要的一点是几乎没有理由打电话Thread.Abort.

MSDN页面:

当一个线程自身调用Abort时,效果类似于抛出异常; ThreadAbortException立即发生,结果是可预测的.但是,如果一个线程在另一个线程上调用Abort,则中止将中断正在运行的任何代码.还有一个机会,一个 静态构造函数可以被中止. 在极少数情况下,这可能会阻止在该应用程序域中创建该类的实例.在.NET Framework版本1.0和1.1中,当finally块正在运行时,线程可能会中止,在这种情况下,finally块将被中止.

如果正在中止的线程位于受保护的代码区域(例如catch块,finally块或约束执行区域),则调用Abort的线程可能会阻塞.如果调用Abort的线程持有中止线程所需的锁,则可能发生死锁.

使用某种形式的信令会更好,例如设置ManualResetEvent每个线程将以perioidic间隔轮询.或者,您可以使用BackgroundWorker对任务取消有一定支持的类(对其进行调用CancelAsync,并让工作线程CancellationPending定期进行测试).如果您使用的是.NET 4.0,则还可以使用TPL.