windows窗体c#中的多线程
本文关键字:多线程 窗体 windows | 更新日期: 2023-09-27 18:12:28
在windows应用程序中,除了主线程之外,还有另一个线程,它每分钟执行一次长时间运行的操作,并使用Invoke方法更新UI。
如何在另一个线程处于睡眠状态时优雅地终止它?
在这里使用睡眠是正确的选择吗?
而不是使线程一次,然后终止,也许使用一个表单定时器触发后台工作线程每60000毫秒?然后你根本不需要休眠后台线程。
这意味着你只需要停止计时器来阻止更多的后台任务被生成,但显然这不会停止任何当前活动的后台线程。
线程应该很少被终止,因为没有任何很好的机制可以保持一致性。有各种各样的保护,比如关键代码标记。然而,我认为最好有一个长时间运行的代码轮询来取消,然后您可以编写自己的逻辑来放弃船只并尽早返回。注意,这与强制终止线程不同。
我不认为睡觉在任何情况下都是正确的选择。
例如:private bool _askedToCancel;
public void lonRunThread()
{
if (!_askedToCancel)
{
Operation1();
Invoke(new UpdateDelegate(updateState));
}
if (!_askedToCancel)
{
Operation2();
Invoke(new UpdateDelegate(updateState));
}
}
看起来有点乱,但是如果你拒绝强制中止线程,而是使用取消方法,你可以很好地控制执行的逻辑。
因为这不是关键代码,而且对布尔值的操作是原子的,所以让两个线程都与布尔值对话而不加任何锁应该是安全的。即使它不是真正的安全,唯一的结果是做了更多的工作。
你可以将线程设置为后台线程,这样当应用程序退出时,线程将自动停止。
您希望线程何时停止?
如果你想让它在操作中途停止,一个布尔标志是合适的。
所以不用
while(true)
你可以这样写
while(exit == false)
不存在优雅的线程终止。相反,应该指示线程在不再需要它时停止它的工作。你可以通过创建一个类来保存工作线程的参数,在这些参数中存储是否应该停止工作的信息,并将该类的一个对象传递给线程来实现这一点。
public class WorkerParams
{
public bool Stop = false;
}
private void TestForm_Load(object sender, EventArgs e)
{
_thread = new Thread(lonRunThread);
_thread.Start(new WorkerParams());
}
public void lonRunThread(object argument)
{
WorkerParams param = argument as WorkerParams;
DateTime lastExec = DateTime.MinValue;
while(!param.Stop)
{
if (new TimeSpan(DateTime.Now.Ticks - lastExec.Ticks).TotalSeconds >= 60)
{
Operation1();
Invoke(new UpdateDelegate(updateState));
Operation2();
Invoke(new UpdateDelegate(updateState));
lastExec = DateTime.Now;
}
Thread.Sleep(500);
}
}
我将改变longRunThread方法中的while(true)并使其
while (_RunLongThread)
然后在TestForm中,我将声明私有布尔值_RunLongThread = true,并从需要停止长时间运行的线程的任何方法将其设置为false。
这是一种"优雅"的停止方式,即等待完成当前任务,然后终止