线程没有足够快地停止

时间:2015-08-07 10:03:32

标签: c# wpf multithreading slider

嗨,抱歉我的英语很差,

在我的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;
    }

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:

 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

正如你所知,当我要求停止时,线程不会停止。

在requestStop之后使用thread.abort解决了我的问题,但它不是停止线程的最优雅方式。

2 个答案:

答案 0 :(得分:3)

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

但无论如何......为什么不在_shouldStop == true?

时打破循环
if (!_shouldStop)
{
  .... generating pictures     
}
else
{
   break;
}

啊,我明白了......你正在设置i的值,以便循环条件改变

答案 1 :(得分:1)

如果你需要在异步情况下(比如两个线程)进行交互(比如停止/启动),总会有延迟。所以你不能期望发出命令“停止”并期望它会立即停止。

想想两个人通过电子邮件进行交流 - 你永远不知道对方何时(即使是)已经阅读过该消息 - 如果你需要知道,你必须等待回复,例如定期检查。

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

  • 另一个选择是实现在线程停止时触发的某种事件,并在“线程停止代码之后”放置它。

  • 如果线程已经停止并且之后继续,您也可以检查一定的间隔。

  • Task这样的一些框架类提供了一种在任务完成后执行某些代码的方法,这可能是“在线程停止代码之后”的地方。

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

有很多选择,每个选项都有不同的复杂性,性能和(dis)优势。选择最适合您需求的产品。