0

在 WPF 应用程序中,我有一个按钮绑定到我的视图模型中的命令。该命令启动一个任务以从数据库中获取信息,然后更新一些属性。

//list in vm to be bound to..
List<DataModel.Item> BoundList;
//new command () =>
{
    var t = Task.Factory.StartNew<IEnumerable<DataModel.Item>>( () =>
       return datasvc.GetItems();
    );
    t.ContinueWith( t2 => {
       BoundList = t.Result;
    }, TaskScheduler.FromCurrentSychronizationContext);
}

t.Result该项目在我使用该标志时报告构建错误FromCurrentSynchronizationContext,但当它不存在时则没有构建错误。问题是我得到一个无响应的用户界面。

我做错了什么?

4

1 回答 1

3

这不是一个标志,它是一个静态方法。此外, t2 是任务的结果,因此您不需要将原始任务存储为单独的变量:

Task.Factory.StartNew(datasvc.GetItems)
    .ContinueWith( 
        t => 
        {
            BoundList = t.Result;
        }, TaskScheduler.FromCurrentSychronizationContext());

如果您的Task对象正在 UI 线程中运行(因此将其冻结),这可能是因为您已经在线程池中运行了多个线程。默认情况下, aTask将在ThreadPool线程上运行,除非它们都被使用。

但是,您可以告知 .NET 这是一个长时间运行的操作,并且它通常会生成额外的线程来阻止您的 UI 冻结。

来自MSDN

TaskCreationOptions.LongRunning
指定任务将是一个长时间运行的粗粒度操作,涉及比细粒度系统更少、更大的组件。它向 TaskScheduler 提供了一个提示,表明可能需要超额订阅。超额订阅允许您创建比可用硬件线程数更多的线程。

因此,您可以将任务创建更改为:

Task.Factory.StartNew(datasvc.GetItems, TaskCreationOptions.LongRunning)
于 2013-07-08T17:07:30.283 回答