【问题标题】:C# Windows Forms Threading: My form seems not to run as own threadC# Windows 窗体线程:我的窗体似乎没有作为自己的线程运行
【发布时间】:2012-03-27 09:18:17
【问题描述】:

我有一个 Windows 窗体。单击“确定”时,将完成一些需要一些时间的工作。在此过程中,表单的所有控件都被禁用,因此用户无法执行某些操作。除了一个按钮,中止。该按钮仍可用于中止流程任务。 我开始一个新线程,很好。问题是当点击 ob abort 时,线程完成后会调用事件。

这是他启动线程的代码(在我的 buttonOk_Click 事件方法中)(我在执行一些数据库操作时使用优先级来假装线程中止):

t1 = new System.Threading.Thread(processing);
t1.Priority = System.Threading.ThreadPriority.Normal;
t1.Start();

这是我捕获中止事件但在线程工作期间未访问的代码。 (使用 ButtonAbort_Click 方法)

while (t1.Priority == System.Threading.ThreadPriority.Highest)
{
    System.Threading.Thread.Sleep(1000);
}
try
{
    lock (t1)
    {
        if (t1.ThreadState != System.Threading.ThreadState.Aborted)
        {
            //abort Thread
            t1.Abort();
            //wait that lock is not released to early
            while (t1.ThreadState != System.Threading.ThreadState.Aborted) { }
        }
    }
}

希望你能帮助我。谢谢。

【问题讨论】:

  • 那里有一些非常奇怪的代码。所有这些优先级检查是为了什么?
  • 不要做 thread.abort() 它会搞砸事情。使用标志并在线程中检查此标志以使其自行停止。

标签: c# winforms multithreading


【解决方案1】:

【讨论】:

    【解决方案2】:

    您的 ButtonAbort_Click 事件处理程序正在围绕 UI 线程旋转。这就是为什么您的表单“似乎不作为自己的线程运行”的原因。您需要做的是让您的processing 方法定期轮询信号以正常终止。中止线程不是一个好主意。这是您的代码的外观。

    class YourForm : Form
    {
      private ManualResetEvent terminate = new ManualResetEvent(false);
    
      private void YourThread()
      {
        while (!terminate.WaitOne(0))
        {
          // Do some more work here.
        } 
      }
    
      private void ButtonAbort_Click(object sender, EventArgs args)
      {
        terminate.Set();
      }
    }
    

    请注意,线程在循环的每次迭代中都调用ManualResetEvent.WaitOne 来测试是否设置了终止信号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 2012-06-15
      相关资源
      最近更新 更多