我的应用监控用户可以上传文件的目录。检测到新文件时,会将其添加到队列中。我有一个运行队列的计时器,并确定文件是否已完成上传。如果有任何文件已完成,则需要使用最新文件并开始运行后台任务(使用BackgroundWorker)。
我的问题是我不知道在后台任务运行时如何处理计时器。例如,如果计时器设置为10秒并且后台工作程序仍在工作,我希望计时器跳过另一个后台工作程序的执行,直到下一次迭代。
此外,每个任务的信息都存储在Queue(ListView控件)中,我将ListViewItem传递给后台worker。如果传递ListViewItem有任何副作用,我很好奇。
谢谢!
答案 0 :(得分:1)
您可以将准备好处理的文件存储在另一个队列中(例如Queue< string>)并让BgWorker不断轮询该队列。您可能也会获得更好的性能,减少空闲时间。您必须保护队列(使用监视器)并让BgWorker在队列为空时使用Monitor.Wait。
要获得一个想法,请在this question上查找Marc Gravell的答案。
答案 1 :(得分:0)
如果没有看到您正在谈论的代码,真的很难回答这个问题。但是,如果必须同步多个异步事件(检测到文件已下载,将文件添加到队列,处理队列),我建议创建一个执行所有任务的BackgroundWorker。然后,您的工作人员可以轻松测试每个步骤的状态。我会避免创建多个线程并尝试同步它们,这是非常有问题的。
我也不会将任何后台任务信息存储在UI数据结构中(如ListView控件)。在BackgroundWorker中创建一个回调或事件,当需要显示内容时,它将提醒用户界面。
答案 2 :(得分:0)
BackgroundWorker.IsBusy Property您要找的是什么?
答案 3 :(得分:0)
您可以做的最简单的事情是在BackgroundWorker中完成所有工作(包括检查文件夹):检查您是否有事可做,如果是,则执行此操作,如果没有,请使用睡眠(时间)或WaitOne(时间) )暂停线程一段时间。
我认为你不需要这里的线程安全队列,因为无论如何都要异步更新文件夹。所以你只需要一个线程,但你需要一种方法来阻止它。这就是AutoResetEvent.WaitOne(时间)优于Sleep(时间)的原因 - 您可以从主线程发出事件信号,以便更早地结束您的后台工作。
答案 4 :(得分:0)
在Timer.Tick处理程序上,检查BackgroundWorker.IsBusy属性以确定它是否已准备好进行其他工作。如果没有,只需跳过工作并等到下一个Tick。
答案 5 :(得分:0)
您可以创建一个线程队列,您可以在其中放置待完成工作。您的后台工作人员在队列中拉出项目并执行工作。 有些事情需要考虑:
另一种更简单的方法是
我没有完全按照你的计时器。如果后台工作人员完成了你应该得到一个事件,你会知道它已经完成,不需要计时器来检查它。