在我们的几何编辑软件中,当用户更改几何体的某些参数(例如某些几何图形的大小或位置)时,应获取并显示几何图形中的“有趣”主要点列表在一张桌子里。因为获得这些点有时会持续几秒钟,所以我们决定使用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
}
}
我现在发现的问题是,虽然不会显示结果,但后台可能会运行很多线程。我已经搜索过,目前尚不清楚是否以及如何“杀死”线程。但也许我可以控制一下如果这些。有什么建议吗?
答案 0 :(得分:1)
Taffer在那里有一些很好的建议,但是由于你有很多后台工作线程,所以它变得更加复杂。
如果你想一次性停止所有这些,你可以通过DoWorkEventArgs.Argument将CancellationToken传递给线程,然后你可以检查令牌是否在backgroundWorker_DoWork中被取消,并且从后面的workWorker_DoWork中取消你只需取消一个CancellationTokenSource
如果你需要个别杀死它们,你需要跟踪它们。把它们放在某种集合中。您仍然可以调用CancelAsync(),但是从backgroundWorker_DoWork内部很难知道哪个线程是您的。我想你可以通过DoWorkEventArgs.Argument传递对线程的引用,并检查CancellationPending。我没试过,但似乎它可以工作。