我有一个方法OnLoadShapeFilePolygonsCommand()
,它从文件中读取多边形(几何)细节并创建一些对象。然后将它们加载到一个可观察的集合中,该集合绑定到数据网格。
虽然所有这些处理,我正在显示进度条。只需添加一个IsIndeterminate
属性设置为true
的进度条,当加载所有数据时,我将进度条的可见性设置为false
。
我的问题是,在创建多边形对象时,UI会被冻结(进度条会挂起)。
我在这里做错了吗?请帮忙。
private async void OnLoadShapeFilePolygonsCommand()
{
// ...
// some code
await Task.Factory.StartNew(() =>
{
List<Ploygon> collection = new List<Ploygon>();
foreach (Graphic g in graphics)
{
collection.Add(new Ploygon(g,.. .. ..);
}
return collection;
},CancellationToken.None, TaskCreationOptions.AttachedToParent, TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith((antecedent) =>
{
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, ThreadStart)delegate ()
{
// MapPolygons is observable collection binded to datagrid.
MapPolygons.AddRange(antecedent.Result);
//...
});
},scheduler);
}
}
答案 0 :(得分:0)
为什么将await
与Task.Factory.StartNew
和ContinueWith
一起使用?
请改为尝试:
var collection = await Task.Run(
() => graphics.Select(g => new Ploygon(g,.. .. ..)).ToList());
// MapPolygons is observable collection binded to datagrid.
MapPolygons.AddRange(collection);
...
答案 1 :(得分:-2)
您正在使用Task.Factory.StartNew
方法的this overload,提供TaskScheduler
作为参数。
您使用静态方法TaskScheduler.FromCurrentSynchronizationContext
获取TaskScheduler
。正如您可以在文档中阅读的那样,此方法返回与当前TaskScheduler
关联的System.Threading.SynchronizationContext
。
由于您在UI线程上调用Task.Factory.StartNew
方法(以及TaskScheduler.FromCurrentSynchronizationContext
方法),实际上您正在使用UI线程的TaskScheduler
来排队工作。这是冻结用户界面的解释。
一方面注意:TaskCreationOptions.AttachedToParent
在这里没用,因为您为父任务指定了此选项。为什么要使用这个选项?
使用快捷方法Task.Factory.StartNew
(当然,如果您的目标是.NET 4.5或更高版本),而不是使用Task.Run
方法。
或者,使用TaskScheduler.Default
代替TaskScheduler.FromCurrentSynchronizationContext()
。