使用任务但UI仍然被阻止

时间:2016-02-04 20:39:09

标签: c# wpf multithreading mvvm

我有一个WPF MVVM c#应用程序。在我的一个视图中,我必须在单击按钮后从数据库中检索数据。 对数据库的调用非常长,所以我想在调用时启用微调器,并在调用完成后禁用它。

所以在处理按钮单击的方法中(使用Command而不是后面的代码)我设置boolean变量以启用微调器,然后创建一个Task来获取数据并将其设置为{{1}像这样

ObservableCollection<T>

完成private void GetDataButtonCommand() { this.IsBusy = true; var tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(() => { System.Windows.Application.Current.Dispatcher.BeginInvoke(new System.Action(() => { var GotData= DBHelper.GetData(); _observablecollectionname.Clear(); foreach (var item in GotData) { _observablecollectionname.Add(item); } })); })); var finalTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), datacomplete => { this.IsBusy = false; }); } 后,我想禁用微调器。

我遇到的问题是我在通话过程中无法看到微调器。即使您使用Task执行数据库查询,UI仍然被阻止。

我做错了什么?

2 个答案:

答案 0 :(得分:5)

您的代码正在UI thead上运行。

您在System.Windows.Application.Current.Dispatcher.BeginInvoke(new System.Action(() => { ... }))中执行所有操作,因此阻止UI很自然。

您只应在真正需要执行UI操作时调用调度程序。

在调度员之前移动var GotData= DBHelper.GetData();

但最好使用C#5.0及更高版本的async / await模式/关键字。

答案 1 :(得分:1)

当我有一个长时间运行的查询时,我总是使用波纹管代码。

    private async void button1_Click(object sender, EventArgs e)
    {
        var list = await GetDatabaseAsync();
        //do whatever you need with the list.
    }



    private async Task<List<string>>  GetDatabaseAsync()
    {
        var list = Task.Run(() =>
        {
            var _observablecollectionname = new List<string>();
            var GotData = Helper.GetData();
            _observablecollectionname.Clear();
            foreach (var item in GotData)
            {
                _observablecollectionname.Add(item);
            }
            return _observablecollectionname;
        });
        return await list;
    }