好吧,我创建了一个循环,创建了很多线程,请参阅:
foreach (DataGridViewRow dgvRow in dataGridView1.Rows)
{
Class h = new Class(dgvRow.Cells["name"].Value.ToString());
Thread trdmyClass = new Thread(h.SeeInfoAboutName);
trdmyClass.IsBackground = true;
trdmyClass.Start();
}
这样可以正常工作,创建我需要的线程,但我希望在我点击一个按钮时,一次性停止所有这些线程(使用Thread.Abort()
)
我怎么能这样做?
答案 0 :(得分:3)
我不会使用Thread.Abort。它可能会产生一些非常令人讨厌的后果。您应该做的是通过将它们放入列表中来跟踪您创建的线程。然后,您可以使用ManualResetEvent类。线程应检查是否定期引发重置,如果已设置,则应清除并退出。我使用WaitOne方法将毫秒超时,然后检查返回值以允许线程在循环中运行。如果返回true,则设置信号,您可以退出循环或从线程返回。如果你使用的是.Net 4,你也可以使用CancelationToken。
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx
在此处详细了解Thread.Abort的问题:http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
编辑:我使用ManualResetEvent作为其线程安全,您可以使用它来同步线程中的处理,例如,如果您正在执行生产者/消费者模式。也可以使用volatile布尔值。我建议将线程保留在列表中,以防您需要等待它们完成,因此您可以加入每个线程。这可能适用于您的问题,也可能不适用。它通常是一个好主意,特别是如果你要离开,加入你所有的线程,让他们完成他们可能正在做的任何清理。
答案 1 :(得分:2)
你真的不应该使用Thread.Abort()
,这可能非常危险。相反,您应该提供一些方法来向线程发出取消它们的信号。然后每个线程会定期检查它是否被取消,如果是,则结束。
执行此操作的一种方法是使用CancellationToken
,这正是如此。支持取消的框架方法也适用于此类型。
您的代码可能如下所示:
// field to keep CancellationTokenSource:
CancellationTokenSource m_cts;
// in your method:
m_cts = new CancellationTokenSource();
foreach (DataGridViewRow dgvRow in dataGridView1.Rows)
{
Class h = new Class(dgvRow.Cells["name"].Value.ToString());
Thread trdmyClass = new Thread(() => h.SeeInfoAboutName(m_cts.Token));
trdmyClass.IsBackground = true;
trdmyClass.Start();
}
//somewhere else, where you want to cancel the threads:
m_cts.Cancel();
// the SeeInfoAboutName() method
public void SeeInfoAboutName(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
// do some work
}
}
答案 2 :(得分:0)
将所有线程保留在List中,然后遍历列表并停止它们。