windows窗体c#中的多线程

本文关键字:多线程 窗体 windows | 更新日期: 2023-09-27 18:12:28

在windows应用程序中,除了主线程之外,还有另一个线程,它每分钟执行一次长时间运行的操作,并使用Invoke方法更新UI。

如何在另一个线程处于睡眠状态时优雅地终止它?

在这里使用睡眠是正确的选择吗?

windows窗体c#中的多线程

而不是使线程一次,然后终止,也许使用一个表单定时器触发后台工作线程每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。

这是一种"优雅"的停止方式,即等待完成当前任务,然后终止