可取消线程队列
本文关键字:队列 线程 可取消 | 更新日期: 2023-09-27 18:15:19
在我们的几何版软件中,当用户改变几何图形的某些参数(例如某些几何图形的大小或位置)时,应从几何图形中获取"有趣"要点列表,并以表格的形式显示出来。因为获得这些点有时需要几秒钟,所以我们决定使用BackGroundWorkers。
我发现的第一个问题是,我必须控制这些点何时被要求计算,因为我只是想显示属于几何体最后变化的点,而不是最后要在BackGroundWorkers中计算的点。我通过添加2个DateTime变量解决了这个问题:一个节省了实际显示点排队计算的时间,另一个节省了实际线程发送实际计算时的时间。当计算完成后,我比较两个日期,并覆盖实际的点列表,如果它是较新的。我这样做与以下代码(在一个用户控制与DataGridView):
/// <summary>
/// Updates the main points.
/// </summary>
/// <param name="track">Track.</param>
public void UpdateMainPoints(Track track)
{
Track = track;
if (backgroundWorker.IsBusy)
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
}
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
Invoke((MethodInvoker) ShowMessage);
}
catch
{
// ignored because it can be called when the window is already closed and it can not be controlled otherwise
}
DateTime jobQueueTime = DateTime.Now;
List<MainPoint> mainPoints = Track.GetMainPoints(_currentUnit);
if (DateTime.Compare(jobQueueTime, _shownPointsQueueTime) > 0)
{
//It updates the actual main point only if the operation was the last one to be calculated
_mainPoints = new List<MainPoint>(mainPoints);
_shownPointsQueueTime = jobQueueTime;
}
//Updates the time in which the shown points where queued to be calculated
try
{
Invoke((MethodInvoker)HideMessageAndShowMainPoints);
}
catch
{
// ignored because it can be called when the window is already closed and it can not be controlled otherwise
}
}
我现在发现的问题是,可以有很多线程在后台运行,虽然他们的结果不会显示。我已经搜索过了,不清楚是否以及如何"杀死"线程。但也许我能控制这些。任何建议吗?
Taffer有一些很好的建议,但是由于你有这么多后台工作线程,它变得更加复杂。
如果你想一次停止它们,你可以通过DoWorkEventArgs向线程传递一个CancellationToken。参数,然后您可以检查令牌是否在backgroundWorker_DoWork中取消,并且从backgroundWorker_DoWork外部取消一个CancellationTokenSource。
如果你需要逐个杀死他们,你需要跟踪他们。把它们收藏起来。你仍然可以调用CancelAsync(),但从backgroundWorker_DoWork内部很难知道哪个线程是你的。我想你可以通过DoWorkEventArgs传递一个引用到线程。参数并检查CancellationPending。我还没有试过,但它似乎可以工作。