【发布时间】:2018-07-15 04:47:34
【问题描述】:
我有一个测量硬件设备,我想通过课程来控制它。我希望能够启动和停止它并让它在自己的线程中进行测量。这样宽度为 2 的按钮我可以开始和停止采样测量,因此我创建了 MeasurementsStart() 和 MeasurementsStop() 两者都是从 2 个按钮调用的。
当在函数 TakeMeasurements() 内部时,我结束
宽度 WorkThread.Abort();
VS2017,说不是所有的代码路径都返回一个值。
当我在适当的位置结束宽度“Throw new NotImplementedException”时,代码会编译它运行,但是当我按下 MeasurementsStart 按钮时,工作线程会继续运行,尽管程序的其余部分会冻结。
我不清楚我应该如何结束这个函数来获得这个开始/停止行为。
此处的实际测量代码已替换为随机数。
Public static Class Measure
{
public static List<double> Samples;
private static Thread workThread;
private static volatile bool stopThread = false;
public static void MeasurementsStop()
{
if (workThread != null)
{
stopThread = true;
workThread.Join(); // pauses till Thread exits.
workThread = null;
}
}
public static void MeasurementsStart()
{
Samples = new List<double>();
if (workThread == null)
{
stopThread = false;
workThread = new Thread(new ThreadStart(TakeMeasurements()));
workThread.IsBackground = true;
workThread.Start();
}
}
private static ThreadStart TakeMeasurements()
{
while (!stopThread )
{System.Console.Beep(200, 200);
Samples.Add(new Random().Next(int.MinValue, int.MaxValue));
System.Console.Beep(400, 200);
}
workThread.Abort();
// throw new NotImplementedException();
}
}
【问题讨论】:
-
不要使用
Abort取消线程。Abort是安全罩下的红色大开关,由两名手持钥匙的警官打开。使用 CancellationToken 检查操作是否需要终止。顺便说一句,static volatile bool stopThread不是线程安全的。在 CancellationToken 之前人们使用 ManualResetEvent 和其他类似的构造,从不使用全局变量 -
如果您想在后台线程中进行定期测量,而不是无限的
while循环,请使用计时器。通常使用 Tasks 而不是原始线程,以便能够组合异步操作,并能够安全地处理它们的结果 -Samples不是线程安全的。 ConcurrentQueue 可能会更好 -
那个'令牌'?是 bool stopThread,我可以删除“workThread.Abort() 但它仍然无法工作,我认为它应该在那里,但它已经是一个不工作的修复程序。
-
@PanagiotisKanavos,在这种情况下,必须在准备好后快速读取测量设备,但对于每个样本,它都会经历一个随机初始化时间。这就是为什么我没有使用计时器,而是使用循环检索。
-
CancellationToken 有效。它不会中止线程,这是一个非常严重的错误。代码检查是否请求取消并优雅地退出循环。已经有很多个重复的问题
标签: c# windows multithreading