使用任务,但 UI 仍被阻止

本文关键字:UI 任务 | 更新日期: 2023-09-27 18:33:26

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

因此,在处理按钮单击的方法中(使用 Command,而不是代码隐藏),我设置了布尔变量以启用微调器,然后创建一个获取数据并将其设置为如下所示ObservableCollection<T>Task

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 仍然被阻止,即使您正在使用Task来执行数据库查询。

我做错了什么?

使用任务,但 UI 仍被阻止

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

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

仅当确实需要执行 UI 操作时,才应调用调度程序。

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

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

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

    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;
    }