1

我在结束一组动态创建的线程时遇到了一些麻烦。我需要在任何给定点结束所有这些的原因是我可以刷新表单的某些部分并创建新的部分。这是一个简单的场景来展示我的线程中发生的事情。

许多线程是根据就地某些变量动态创建的:

 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 之前中止这组线程?

4

3 回答 3

2

你有几个问题。

  • 您正在关闭一个循环变量
  • 您创建一个线程的唯一目的是启动计时器......为什么不在主线程中启动计时器?
  • 您的计时器实例未植根,因此在您完成之前它可能有资格进行垃圾收集。
  • System.Timers.Timer事件处理程序将在一个线程上执行(ThreadPool至少在这种情况下),因此尝试中止这些线程之一不会很好地结束。

这里有足够多的问题,在我们回答您的主要问题之前,您将进行一些重大的重组。还有一个提示……不要尝试从主 UI 线程以外的线程访问或操作任何 UI 元素。

于 2012-05-31T13:20:50.053 回答
0

你为什么在你的线程过程中使用计时器?

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.Set()

于 2012-05-31T09:55:43.320 回答
0

我在我的一个解决方案中使用它http://msdn.microsoft.com/en-us/magazine/cc163644.aspx

它是 AbortableThreadPool。可能对你有用。

也有点困惑为什么你在 timerElapsed 中调用 Thread.Abort 在一个已经完成的线程上

于 2012-05-31T09:56:01.440 回答