如何加入/中止一组动态创建的线程
本文关键字:一组 动态 创建 线程 何加入 | 更新日期: 2023-09-27 18:35:47
我在结束一组动态创建的线程时遇到了一些麻烦。我需要在任何给定点结束所有这些的原因是,我可以刷新表单的某些部分并创建新部分。这是一个简单的场景来显示我的线程中发生的情况。
许多线程是根据某些变量动态创建的:
for (int i = 0; i <= mDevices.Count; i++)
{
ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this); };
new Thread(workerThread).Start();
}
public void pollDevices(IDeviceInterface device, DeviceManager mainUI)
{
System.Timers.Timer timer = null;
if (timer == null)
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += delegate(object sender, ElapsedEventArgs e) { timerElapsed(sender, e, device, mainUI); };
}
timer.Enabled = true;
public void timerElapsed(object sender, ElapsedEventArgs e, IDeviceInterface device, DeviceManager mainUI)
{
device.connect(device, this);
//wait till thread finishes and destroy
Thread.CurrentThread.Abort();
}
然后,这些线程在计时器上工作,并处理处理 UI 更新等的事件。 但是,当我尝试刷新 UI 时(例如,如果需要考虑数据库中的任何其他条目),如果线程仍在运行,则删除表单上的按钮(这些按钮分配给线程)时出现错误, 因此,在我调用刷新之前,我需要以这种方式停止所有当前线程。
所以我的问题是,如何在刷新 UI 之前中止这组线程?
你有几个问题。
- 您正在关闭循环变量。
- 您正在创建一个线程,其唯一目的是启动计时器...为什么不直接在主线程中启动计时器?
- 您的计时器实例未获得 root 根,因此在您完成它之前,它可能有资格进行垃圾回收。
System.Timers.Timer
事件处理程序将在ThreadPool
线程上执行(至少在这种情况下),因此尝试中止其中一个线程不会有好结果。
这里有足够多的问题,在我们回答您的主要问题之前,您将进行一些重大重组。不过还有一个额外的提示...不要尝试从主 UI 线程以外的线程访问或操作任何 UI 元素。
为什么要在线程进程中使用计时器?
ManualResetEvent exit = new ManualResetEvent(false);
for (int i = 0; i <= mDevices.Count; i++)
{
ThreadStart workerThread = delegate { pollDevices(mDevices[i - 2], this, exit); };
new Thread(workerThread).Start();
}
public void pollDevices(IDeviceInterface device, DeviceManager mainUI, ManualResetEvent exit)
{
while(!exit.WaitOne(1000))
{
// do work
device.connect(device, this);
}
}
然后,如果要停止所有线程,只需调用 exit。设置()
我在我的一个解决方案中使用它 http://msdn.microsoft.com/en-us/magazine/cc163644.aspx
它是AbortableThreadPool。可能适合您。
也有点困惑,为什么你在计时器中调用 Thread.Abort 无论如何都在完成的线程上