线程停止得不够快

本文关键字:不够 线程 | 更新日期: 2023-09-27 18:07:02

大家好,很抱歉我的英语不好,

在我的WPF应用程序中,我有一个可增加滑块值的RepeatButton。

每次滑动条值改变时,我必须停止正在生成图片的线程,并根据新的滑动条值再次运行相同的线程:

  Console.WriteLine("Request stop !");
                requestStop();
                Console.WriteLine(bw.IsAlive.ToString());
                valuetogenerate = searchValueToGenerate();
                bw = new Thread(() => bw_DoWork());
                requestStart();
                bw.Start();

声明
 private volatile bool _shouldStop;

我的requestStop和start方法:

  public void requestStop()
    {
        _shouldStop = true;
    }
    public void requestStart()
    {
        _shouldStop = false;
    }

And the DoWork:

 while (!_shouldStop && !(allvaluegenerated))
        {
            for (int i = 0; i < valuetogenerate.Count - 1; i++)
            {
             Console.WriteLine("i :" + i + " " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
                if (!_shouldStop)
                {
                      .... generating pictures     
                }
                else
                {
                     i = valuetogenerate.Count + 1;
                }
            }
        }
 Console.WriteLine("Thread stopped");

问题是线程没有停止得足够快(我认为…),这是我的输出窗口后线程id I值:

 Number of value to generate : 6
 Begin generation : 
 i :0 15
 i :1 22
 i :1 23
 i :2 21
 i :2 20
 i :1 19
 i :1 15
 i :2 22
 i :2 23
 i :2 19
 i :3 20
 i :3 21
 i :2 15
 i :3 19
 i :3 22
 i :3 23
 i :4 20
 i :4 21
 i :3 15
 i :4 22
 i :4 19
 Thread stopped
 i :4 23
 Thread stopped
 i :4 15
 Thread stopped
 Thread stopped
 Thread stopped
 Thread stopped

你可以看到,当我请求停止时,线程没有停止。

使用线程。abort after requestStop解决了我的问题,但它不是最优雅的方式来停止线程。

线程停止得不够快

你应该只请求一个线程被取消,并让线程自己处理这个取消过程。如果这意味着线程需要一段时间才能这样做,那么就这样吧。终止线程只能作为最后的手段。

但无论如何……当_shouldStop == true时,为什么不中断循环呢?

if (!_shouldStop)
{
  .... generating pictures     
}
else
{
   break;
}

啊,我明白了…您正在设置I的值,以便循环条件改变

如果您需要在异步情况下(如两个线程)进行交互(如停止/启动),则总是会有延迟。因此,您不能期望发出"stop"命令并期望它立即停止。

想象两个人通过电子邮件交流——你永远不知道对方什么时候(即使)读了邮件——如果你需要知道,你必须等待回复,比如定期检查。

  • 一种方法是阻塞自己的线程直到另一个线程停止,这样你可以保持你的程序流(但不能在主线程中做任何其他事情)。

  • 另一个选项是实现某种在线程停止时触发的事件,并在那里放置"after the thread has stopped code"

  • 你也可以在一定的时间间隔内检查线程是否已经停止,然后继续。

  • 一些框架类,如Task,提供了在任务完成后执行一些代码的方法,这可能是一个"线程停止后代码"的地方。

  • async/await模式也可能对您有所帮助。看看这一页。我认为这是最先进的方法,一旦你习惯了,也很容易使用。

有很多选择,每个都有不同的复杂性、性能和(缺点)优势。选择一个最适合你需要的