C# 任务在通知进度之前完成。为什么以及如何修复?
因此,我尝试使用C# 任务在通知进度之前完成。为什么以及如何修复?,c#,wpf,asynchronous,task,C#,Wpf,Asynchronous,Task,因此,我尝试使用IProgress使用任务进度通知。以下是我的工作: 创建一个Progress并将处理程序附加到其ProgressChanged事件 在事件处理程序中,我更新UI特定属性以显示进度 运行循环并创建任务对象以完成工作单元。每个任务都使用Progress对象来报告进度(这将依次调用ProgressChanged并更新UI) 使用Task.WaitAll()阻止,直到所有任务完成。在结尾显示完成消息 代码如下所示: IProgress<Tuple<DataRow, MyVM
IProgress
使用任务进度通知。以下是我的工作:
Progress
并将处理程序附加到其ProgressChanged
事件任务
对象以完成工作单元。每个任务都使用Progress
对象来报告进度(这将依次调用ProgressChanged
并更新UI)Task.WaitAll()
阻止,直到所有任务完成。在结尾显示完成消息IProgress<Tuple<DataRow, MyVM>> BakeProgress;
BakeProgress = new Progress<Tuple<DataRow, MyVM>>();
((Progress<Tuple<DataRow, MyVM>>)BakeProgress).ProgressChanged += (sender, args) =>
{
_BakeProgress += 100.0 / AllDataRows.Length;
RaisePropertyChanged(NameOf(BakeProgress));
};
var BakeTasks = new List<Task>();
foreach (var dr in AllDataRows) {
BakeTasks.Add(Task.Run(() =>
{
var Baked = MyBakingFunc();
BakeProgress.Report(new Tuple<DataRow, MyVM>(dr, Baked));
return Baked;
}));
}
Task.WaitAll(BakeTasks.ToArray()); //Shouldn't this wait
MessageBox.Show("Baking Completed");
IProgress-BakeProgress;
BakeProgress=新进展();
((进度)BakeProgress.ProgressChanged+=(发送方,参数)=>
{
_BakeProgress+=100.0/AllDataRows.Length;
RaisePropertyChanged(BakeProgress)名称);
};
var BakeTasks=新列表();
foreach(所有数据行中的var dr){
BakeTasks.Add(Task.Run)(()=>
{
var Baked=MyBakingFunc();
BakeProgress.Report(新元组(dr,Baked));
返烤;
}));
}
Task.WaitAll(BakeTasks.ToArray())//这不是应该等一下吗
MessageBox.Show(“烘焙完成”);
令我惊讶的是,此代码在命中ProgressChanged
事件处理程序之前,甚至只命中了MessageBox
line。我做错了什么
注意:对于每个任务实例,它确实会命中ProgressChanged
事件处理程序一次,但只有在命中完成行之后才会命中
注意:啊,我确实读过,但由于这是WPF,我们确实有一个同步上下文,在其中创建了
进度
对象。提示:您不需要任务。运行,您应该使用等待任务。当所有而不是任务。WaitAll
时,请使用camelCase
作为局部变量和参数,不是PascalCase
@Dai:谢谢。为什么我不需要任务。运行?你是说我不应该使用多线程吗?正如你所看到的,在你的例子中,进程处理程序将在UI线程上运行。但您的UI在等待所有任务完成时被阻止。因此,只有在所有任务完成(并显示消息框)后,UI线程才可用于运行进度处理程序。@Dai:我对参数使用camelCase,但对局部变量使用PascalCase。不确定我是什么时候开始采用这种风格的,但它有时确实对我有所帮助。