gpt4 book ai didi

除非我单步执行代码,否则 C# 线程不会正确终止

转载 作者:太空宇宙 更新时间:2023-11-03 10:43:00 24 4
gpt4 key购买 nike

我的线程 (_updater) 是这样启动的:

 public void StartCollection()
{
running = true;
_updater = new Thread(new ThreadStart(ContinuousCollect));
_updater.Start();
}

然后它从传感器获取数据并将其发送到需要的地方。

private void ContinuousCollect()
{
while (running) //Static Boolean that controls whether or not to keep running.
{
lock (_data)
ReadData(ref _data);

//Stuff that doesn't matter
}
}

然后通过这个方法停止:

 public void StopCollection()
{
if (_updater != null)
{
if (_updater.ThreadState == ThreadState.Running)
{
running = false;
_updater.Join();
}

_updater = null;
}
}

当我在没有断点的情况下正常运行它时,它会在尝试读取数据时抛出错误,但我已经关闭了 COM 端口 - 它不应该这样做,因为我试图结束线程。当我在 StopCollection() 中使用断点并单步执行时,它会正确地将运行更改为 false 并且 _updater 逐渐停止,从而不会出现任何错误。如果没有断点,即使在我调用 StopCollection() 之后,_updater 仍会继续运行,并且 running 仍设置为 true,即使代码中我将其设置为 true 的唯一位置是在 StartCollection() 中。我尝试使用 Thread.Abort 但这也不起作用。我能做什么?

最佳答案

您没有同步对线程之间共享的内存的访问,这是问题的根源。只要您不通过使用内存屏障明确禁止它这样做,每个线程都能够缓存特定内存状态的值,因此您的工作线程永远不会检查内存中的实际位置以查看你已经更新了变量。

虽然您可以通过某种方式显式同步对变量的访问以确保从多个线程正确访问它,但更惯用的解决方案是使用 CancellationToken,因为它是实现将确保共享状态的正确同步,防止 token 是否已取消的状态缓存在其他线程中。

当调试时,所有类型的优化都被移除,以及其他以改变未定义行为结果的方式修改的行为,例如这个行为,这就是为什么您的程序在使用调试器时表现不同的原因。线程相关的错误通常很难/不可能使用调试器重现,就其本质而言,因为您观察行为的行为会改变行为本身,这就是为什么在多线程环境中编程时需要更加小心的原因使用共享内存。

关于除非我单步执行代码,否则 C# 线程不会正确终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24613529/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com