C# 无阻塞的顺序异步任务
我有一个C#WPF应用程序,它使用了一种非常简单的MVVM方法。在其中一个ViewModels中,我希望按顺序运行一系列任务,但希望运行每个异步到主线程。我希望能够报告任务之间的进度,但我不希望在任何任务运行时阻塞GUI 是否有实现这一目标的标准方法,或“最佳实践” 我已经实现了一些利用了C# 无阻塞的顺序异步任务,c#,wpf,asynchronous,C#,Wpf,Asynchronous,我有一个C#WPF应用程序,它使用了一种非常简单的MVVM方法。在其中一个ViewModels中,我希望按顺序运行一系列任务,但希望运行每个异步到主线程。我希望能够报告任务之间的进度,但我不希望在任何任务运行时阻塞GUI 是否有实现这一目标的标准方法,或“最佳实践” 我已经实现了一些利用了BackgroundWorker的东西,这让我感到既高兴又有点害怕。启动整个过程的代码让人感觉特别不舒服。我觉得必须有一种更好的方法,或者至少是一种既定的方法来做到这一点 非常感谢你的建议 丹 以下是拼凑在一
BackgroundWorker
的东西,这让我感到既高兴又有点害怕。启动整个过程的代码让人感觉特别不舒服。我觉得必须有一种更好的方法,或者至少是一种既定的方法来做到这一点
非常感谢你的建议
丹
以下是拼凑在一起的选项:
protected void runAsyncTask(SequentialTask seqTask)
{
if (HasErrored) return;
DoWorkEventHandler worker = (s, e) =>
{
setTaskStartStatusMessage(seqTask.TaskMessage);
ShowProgress = true;
seqTask.Task((BackgroundWorker)s);
};
ProgressChangedEventHandler progress = (s, e) =>
{
if (seqTask.TaskProgress != null)
seqTask.TaskProgress(e.ProgressPercentage, e.UserState);
};
RunWorkerCompletedEventHandler done = null;
done = (s, e) =>
{
ShowProgress = false;
if (e.Error != null)
{
HasErrored = true;
displayTaskExceptionMessage(e.Error, seqTask.TaskMessage);
}
else
{
setTaskCompleteStatusMessage(seqTask.TaskMessage);
if (seqTask.TaskComplete != null)
seqTask.TaskComplete();
}
((BackgroundWorker)s).RunWorkerCompleted -= done;
((BackgroundWorker)s).DoWork -= worker;
((BackgroundWorker)s).ProgressChanged -= progress;
if (seqTask.NextTask != null && (seqTask.CanExecuteNext == null ? true : seqTask.CanExecuteNext()))
runAsyncTask(seqTask.NextTask);
};
if (seqTask.TaskProgress != null)
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += worker;
backgroundWorker.RunWorkerCompleted += done;
backgroundWorker.ProgressChanged += progress;
backgroundWorker.RunWorkerAsync();
}
SequentialTask
只是一组简单的属性:
public class SequentialTask
{
public Action<BackgroundWorker> Task { get; set; }
public String TaskMessage { get; set; }
public Func<bool> CanExecuteNext { get; set; }
public Action<int, object> TaskProgress { get; set; }
public Action TaskComplete { get; set; }
public SequentialTask NextTask { get; set; }
}
等等。我认为你的方法没有任何问题。最重要的是:它可以工作。您看过.NET4.0中的任务并行库(TPL)了吗?这允许您执行以下操作:
Task firstTask = new Task(()=>RunStepOne());
firstTask.ContinueWith(task=>()=>RunSecondStep());
firstTask.Start();
创建、继续和停止TPL上构建的任务有很多选项。当然值得一看。协同程序或反应式框架非常适合这样做:嗨,Jay,谢谢你的链接-快速浏览一下,我肯定会花时间想一想,但我认为Adam的TPL建议是我最初努力的方向。更不用说,这会在C#5发布时帮你一把。谢谢Adam,简言之,这是C#的下一章——我会继续看下去。从您展示的代码片段来看,它显然比链接递归结构要干净得多。我认为这肯定能满足我的需要,而且是“开箱即用”,再次感谢。
Task firstTask = new Task(()=>RunStepOne());
firstTask.ContinueWith(task=>()=>RunSecondStep());
firstTask.Start();