嗨,抱歉我的英语很差,
在我的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解决了我的问题,但它不是停止线程的最优雅方式。
答案 0 :(得分:3)
您应该只请求取消线程并让线程自己处理该取消过程。如果这意味着线程需要一段时间才能这样做,那就这样吧。中止线程只能作为最后的手段。
但无论如何......为什么不在_shouldStop == true?
时打破循环if (!_shouldStop)
{
.... generating pictures
}
else
{
break;
}
啊,我明白了......你正在设置i的值,以便循环条件改变
答案 1 :(得分:1)
如果你需要在异步情况下(比如两个线程)进行交互(比如停止/启动),总会有延迟。所以你不能期望发出命令“停止”并期望它会立即停止。
想想两个人通过电子邮件进行交流 - 你永远不知道对方何时(即使是)已经阅读过该消息 - 如果你需要知道,你必须等待回复,例如定期检查。
一种方法是阻止自己的线程直到另一个线程停止,这样你就可以保持你的程序流程(但不能在主线程中做任何其他事情)。
另一个选择是实现在线程停止时触发的某种事件,并在“线程停止代码之后”放置它。
如果线程已经停止并且之后继续,您也可以检查一定的间隔。
像Task
这样的一些框架类提供了一种在任务完成后执行某些代码的方法,这可能是“在线程停止代码之后”的地方。
async
/ await
模式也可能对您有所帮助。看看this page。我认为这是最先进的方法,一旦你习惯它也很容易使用。
有很多选择,每个选项都有不同的复杂性,性能和(dis)优势。选择最适合您需求的产品。