C# 从主UI线程上的按钮挂起子线程

C# 从主UI线程上的按钮挂起子线程,c#,C#,我已经找到了这个话题,但对于我想要达到的目标,却没有令人满意的答案 我使用线程和WatiN类在同一个windows窗体的两个浏览器上同时执行事件 我想从主UI线程中,按下其中一个浏览器中可用的暂停按钮,通过导出按下暂停按钮的浏览器的控件名称,使用该名称找出哪个子线程与其运行逻辑关联,并暂停运行逻辑,直到按下播放按钮 现在,我们在代码和技术方面已经取得了很大的成就,应该有办法做到这一点 你觉得怎么样 研究思路: 实用地创建ManualResetEvent并命名它,使用UI pause按钮获取打开的

我已经找到了这个话题,但对于我想要达到的目标,却没有令人满意的答案

我使用线程和WatiN类在同一个windows窗体的两个浏览器上同时执行事件

我想从主UI线程中,按下其中一个浏览器中可用的暂停按钮,通过导出按下暂停按钮的浏览器的控件名称,使用该名称找出哪个子线程与其运行逻辑关联,并暂停运行逻辑,直到按下播放按钮

现在,我们在代码和技术方面已经取得了很大的成就,应该有办法做到这一点

你觉得怎么样

研究思路:

实用地创建ManualResetEvent并命名它,使用UI pause按钮获取打开的浏览器控件名称,该名称类似于子线程和浏览器控件名称,例如浏览器5和线程5以某种方式指向子线程中的MRE,并关闭门以暂停逻辑。但是这可以在主UI线程的子线程上完成吗?

不要使用线程。挂起 乍一看,你似乎可以而且。但这不是一个好主意。请参阅,除非您打算终止该线程的AppDomain

不要使用Suspend和Resume方法来同步线程的活动。挂起线程时,无法知道线程正在执行什么代码。如果在安全权限评估期间挂起一个线程,而该线程持有锁,则AppDomain中的其他线程可能会被阻止。如果在线程执行类构造函数时挂起该线程,则AppDomain中尝试使用该类的其他线程将被阻止。死锁很容易发生

子循环可以工作,但并不完美 这不是最好的选择,但您可以使用类似的技术来实现

不要在按下停止按钮时退出循环,而是让它在暂停时进入子循环并在子循环内等待。做一个线程。在子循环中睡眠以防止CPU死机

这不是可能的最有效的代码,因为它保持线程运行,并在恢复时再挂起100毫秒

public class YourForm : Form
{
  private volatile bool _pause = false;

  private void StartButton_Click(object sender, EventArgs e)
  {
    var thread = new Thread(
      () =>
      {
        while (...)
        {
          // Periodically poll the _pause flag.
          while (_pause)
          {
            // Now that we're paused, wait until we're unpaused
            // before proceeding further in the outer loop
            Thread.Sleep(100);
          }

          // Todo: The rest of the processing here
        }
      });
    thread.Start();
  }

  private void PauseButton_Click(object sender, EventArgs e)
  {
    _pause = !_pause; // Toggle
  }
}
使用线程同步 最好的选择是使用各种线程同步结构之一。暂停线程正是它们的设计目的。他们非常有效率,因为他们是

不要使用线程。挂起 乍一看,你似乎可以而且。但这不是一个好主意。请参阅,除非您打算终止该线程的AppDomain

不要使用Suspend和Resume方法来同步线程的活动。挂起线程时,无法知道线程正在执行什么代码。如果在安全权限评估期间挂起一个线程,而该线程持有锁,则AppDomain中的其他线程可能会被阻止。如果在线程执行类构造函数时挂起该线程,则AppDomain中尝试使用该类的其他线程将被阻止。死锁很容易发生

子循环可以工作,但并不完美 这不是最好的选择,但您可以使用类似的技术来实现

不要在按下停止按钮时退出循环,而是让它在暂停时进入子循环并在子循环内等待。做一个线程。在子循环中睡眠以防止CPU死机

这不是可能的最有效的代码,因为它保持线程运行,并在恢复时再挂起100毫秒

public class YourForm : Form
{
  private volatile bool _pause = false;

  private void StartButton_Click(object sender, EventArgs e)
  {
    var thread = new Thread(
      () =>
      {
        while (...)
        {
          // Periodically poll the _pause flag.
          while (_pause)
          {
            // Now that we're paused, wait until we're unpaused
            // before proceeding further in the outer loop
            Thread.Sleep(100);
          }

          // Todo: The rest of the processing here
        }
      });
    thread.Start();
  }

  private void PauseButton_Click(object sender, EventArgs e)
  {
    _pause = !_pause; // Toggle
  }
}
使用线程同步 最好的选择是使用各种线程同步结构之一。暂停线程正是它们的设计目的。他们非常有效率,因为他们是

你的想法完全正确

使子线程在每个步骤之间的事件上等待一个。 要暂停请求,请调用Reset;要取消暂停,请调用Set

如果设置了事件,WaitOne将立即返回

这将比反复睡眠更有效率

我怀疑ManualResetEventSlim会稍微快一点。

你的ManualResetEvent想法完全正确

使子线程在每个步骤之间的事件上等待一个。 要暂停请求,请调用Reset;要取消暂停,请调用Set

如果设置了事件,WaitOne将立即返回

这将比反复睡眠更有效率

我怀疑一个苗条的人会稍微快一点