0

我的应用程序监视用户可以上传文件的目录。当检测到新文件时,会将其添加到队列中。我有一个计时器,它在队列中运行并确定文件是否已完成上传。如果有任何文件是完整的,它将采用最新的并开始运行后台任务(使用 BackgroundWorker)。

我的问题是我不知道如何在后台任务运行时处理计时器。例如,如果计时器设置为 10 秒并且后台工作人员仍在工作,我希望计时器在下一次迭代之前跳过另一个后台工作人员的执行。

此外,每个任务的信息都存储在队列(ListView 控件)中,我将 ListViewItem 传递给后台工作人员。我很好奇传递 ListViewItem 是否有任何副作用。

谢谢!

4

6 回答 6

1

您可以将准备处理的文件存储在另一个队列中(例如 Queue<string> )并让 BgWorker 不断轮询该队列。您也可能获得更好的性能,更少的空闲时间。当队列为空时,您必须保护队列(使用 Monitor)并让 BgWorker 使用 Monitor.Wait。

要获得一个想法,请查看 Marc Gravell对此问题的回答。

于 2009-06-22T22:31:47.913 回答
0

如果没有看到您正在谈论的代码,真的很难回答这个问题。但是,如果您必须同步多个异步事件(检测文件已下载、将文件添加到队列、处理队列),我建议创建一个可以执行所有任务的 BackgroundWorker。然后,您的工作人员很容易测试每个步骤的状态。我会避免创建多个线程并尝试同步它们,这是非常有问题的。

我也不会在 UI 数据结构(如 ListView 控件)中存储任何后台任务信息。在 BackgroundWorker 中创建一个回调或事件,当 UI 需要显示某些内容时会提醒它。

于 2009-06-22T22:34:03.557 回答
0

BackgroundWorker.IsBusy 属性是您正在寻找的吗?

于 2009-06-22T22:34:35.897 回答
0

您可以做的最简单的事情是在 BackgroundWorker 中完成所有工作(包括检查文件夹):检查您是否有事要做,如果有,就去做,如果没有,使用 Sleep(time) 或 WaitOne(time) 暂停线程一段时间。

我认为您在这里不需要线程安全队列,因为无论如何文件夹都是异步更新的。所以你只需要一个线程,你需要一种方法来阻止它。这就是为什么 AutoResetEvent.WaitOne(time) 会比 Sleep(time) 更好 - 您可以从主线程发出事件信号以提前结束您的后台工作人员。

于 2009-06-22T22:36:00.713 回答
0

在 Timer.Tick 处理程序上,检查BackgroundWorker.IsBusy属性以确定它是否已准备好进行另一项工作。如果没有,就跳过它的工作,等到下一个 Tick。

于 2009-06-22T22:36:09.917 回答
0

您可以创建一个线程队列,在其中放置待办事项。您的后台工作人员循环从队列中取出项目并执行工作。有些事情需要考虑:

  • 队列需要是线程安全的,如果队列为空,您很可能希望后台工作程序阻塞,并在项目可用时唤醒。我确定有人已经排了这么好的队列。
  • 您发布到队列的项目将在另一个线程(后台工作程序)中进行操作。确保这是以线程安全的方式完成的(例如,不要将项目发布到主应用程序和后台工作人员都会改变的队列)

另一种更简单的方法是

  • 在您的应用程序中排队项目。第一次启动后台工作人员。
  • 当您收到后台工作程序完成的事件时,从队列中选择下一个项目并使用该项目再次启动后台工作程序。
  • 您仍然需要关心线程安全。当您向后台工作人员发送项目时,请确保只有后台工作人员对其进行操作(例如,如果您只是向其发送字符串,则改为向其发送所述字符串的副本)

我没有完全按照你的时间来。如果后台工作人员完成,您应该得到一个事件并且您会知道它已经完成,不需要计时器来检查这一点。

于 2009-06-22T22:46:59.490 回答