我希望在另一个完成之后开始BackgroundWorker
。我不确定如何为它编写代码,所以我真的没有任何东西要显示。
我考虑过在RunWorkerCompleted
中写一下,但这似乎是错误的地方,可以用来启动另一个工人。
我应该在哪里以及如何做到这一点?
基本上,我想使用同一个工人,但要做其他事情。与步骤1中的数据一样,它解析文件中的数据,在步骤2中,在步骤1完成后,它应该将解析后的数据从内存写入数据库。
答案 0 :(得分:4)
您可以使用.NET 4.0 Task类,然后使用Task.ContinueWith排队更多工作。
答案 1 :(得分:3)
最好使用两个不同的BackgroundWorker
组件。在第一个RunWorkerCompleted
事件处理程序中启动第二个。这似乎是一种非常合理的做事方式。只是不要尝试使用单个BackgroundWorker
。
作为Tudor mentioned,您可以使用Task
,但随后会失去BackgroundWorker
的便利性,其中包含熟悉的面向事件的界面,进度报告等。
答案 2 :(得分:3)
从您的描述看来,步骤是相关的和顺序的,所以我将它实现为单个BGW,其中DoWork
执行两个步骤,在解析步骤和写入之间调用ReportProgress
到数据库步骤。
然后,您可以处理在UI线程上运行的ProgressChanged
事件,以便在解析步骤完成后执行任何逻辑,因为知道该工作者已经在写入数据库。
ReportProgress
接受一个整数来标识后台任务的完成百分比和可选的自定义对象。因此,在ProgressChanged
处理程序中,您需要具有解释此进度信息的逻辑。在这种情况下,作为两步工作,您只需拨打ReportProgress(50)
。
答案 3 :(得分:1)
如果使用第三方库进行作业调度是可以接受的,请查看 Quartz.NET ,并在此处描述它的作业监听器机制http://quartznet.sourceforge.net/tutorial/lesson_7.html。如果你想自己实现它,我会使用一个BackgroundWorker
来执行一系列组织成责任链的工作,你可以在这里阅读更多关于这个模式的信息{{ 3}}
答案 4 :(得分:0)
这将允许使用一名后台工作者进行多次后续操作:
private void DoBackgroundWork<T>(string name, Func<T> work, Action<T> onComplete)
{
lblCurrentOperation.Text = name;
StaticClass.OnProgress = (p) => backgroundWorker1.ReportProgress(p);
T result = default(T);
var handler = new DoWorkEventHandler((s, e) =>
{
result = work();
});
backgroundWorker1.DoWork += handler;
RunWorkerCompletedEventHandler completedHandler = null;
completedHandler = new RunWorkerCompletedEventHandler((s, e) =>
{
onComplete(result);
backgroundWorker1.DoWork -= handler;
backgroundWorker1.RunWorkerCompleted -= completedHandler;
lblCurrentOperation.Text = string.Empty;
progressBar1.Value = 0;
});
backgroundWorker1.RunWorkerCompleted += completedHandler;
}
用法:
DoBackgroundWork("Loading resources",
() =>
{
return DoWork();
},
(result) =>
{
//final UI operations
Task.Delay(500).ContinueWith(t => this.Invoke((Delegate)new Action(() => anotherOperationWithSameWorker())));
});
backgroundWorker1.RunWorkerAsync();