Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# windows窗体C中的多线程处理#_C#_.net_Winforms - Fatal编程技术网

C# windows窗体C中的多线程处理#

C# windows窗体C中的多线程处理#,c#,.net,winforms,C#,.net,Winforms,在windows应用程序中,除了主线程外,还有一个线程每分钟执行一次长时间运行操作,并使用Invoke方法更新UI 当另一个线程处于睡眠状态时,我们如何优雅地终止它 在这里使用sleep是正确的选择吗?与其让线程运行一次然后终止,不如使用窗体计时器每隔60000毫秒触发一个后台工作线程?然后,您根本不需要休眠背景线程 这意味着您只需要停止计时器来停止生成更多的后台任务,但显然这不会停止任何当前活动的后台线程 线程应该很少被中止,因为没有任何好的机制可以以任何一致性进行中止。有各种保护措施,如关键

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

当另一个线程处于睡眠状态时,我们如何优雅地终止它


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

与其让线程运行一次然后终止,不如使用窗体计时器每隔60000毫秒触发一个后台工作线程?然后,您根本不需要休眠背景线程

这意味着您只需要停止计时器来停止生成更多的后台任务,但显然这不会停止任何当前活动的后台线程

线程应该很少被中止,因为没有任何好的机制可以以任何一致性进行中止。有各种保护措施,如关键代码标记。然而,我认为最好是对取消进行长时间运行的代码轮询,然后您可以编写自己的逻辑,以便弃船并提前返回注意,这与强制中止线程不同

我不认为在任何情况下睡觉都是正确的选择

例如:

private bool _askedToCancel;

public void lonRunThread()
{
    if (!_askedToCancel)
    {
        Operation1();
        Invoke(new UpdateDelegate(updateState));
    }

    if (!_askedToCancel)
    {    
        Operation2();
        Invoke(new UpdateDelegate(updateState));
    }
}
看起来有点混乱,但是如果拒绝强制中止线程,而是使用取消方法,则可以很好地控制执行什么逻辑


因为这不是关键代码,而且布尔操作是原子的,所以让两个线程在没有任何锁定的情况下与布尔对话应该是安全的。即使它不是真正安全的,唯一的结果就是做了更多的工作。

不是让线程运行一次然后终止,而是使用窗体计时器每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)

您可以始终将线程设置为后台线程,这样当应用程序退出时,线程将自动停止

您希望线程何时停止

如果希望在操作中间停止,则布尔标志将是合适的

所以不是

while(true)
你会这样做

while(exit == false)
我将更改longRunThread方法中的while(true)并使其

while (_RunLongThread)
然后,在TestForm中,我将声明私有布尔值_RunLongThread=true,并将其设置为false,无论哪个方法需要停止长时间运行的线程

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

我将更改longRunThread方法中的while(true)并使其生效

while (_RunLongThread)
然后,在TestForm中,我将声明私有布尔值_RunLongThread=true,并将其设置为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);
    }
}

没有优雅的线程终止。相反,当不再需要线程时,应该指示线程停止它的工作。您可以通过创建一个类来保存工作线程参数,在该类中存储是否应该停止工作的信息,并将该类的对象传递给线程

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);
    }
}

那么,上述方法会让最终用户等待,然后您将需要更复杂的处理。使用1000ms睡眠,并计算自上次执行以来是否经过了足够的时间。好的,上述方法会让最终用户等待,然后您将需要更复杂的处理。执行1000ms睡眠,并计算自上次执行以来是否经过了足够的时间。实际上,OPeration1()和OPeration2()有一些非托管代码。如果在处理OPeration1()或OPeration2()时线程突然终止,则会导致内存泄漏。另一方面,您必须在非托管代码中使用指针吗?我理解这一点。我的问题是,你能不使用指针就离开吗?例如,你没有C=新的C();但是,您可以编写它,以便在函数超出范围时自动销毁对象,即C;c、 长_操作();不目前,由于内存不足,当对象超出范围时,无法自动销毁该对象