[英]Using Tasks but the UI is still blocked
I have a WPF MVVM c# application. 我有一个WPF MVVM c#应用程序。 In one of my views I have to retrieve data from the database after a button is clicked.
在我的一种视图中,单击按钮后,我必须从数据库中检索数据。 The call to the database is really long and so I want to enable a spinner while the call is being made and disable it when the call is done.
对数据库的调用确实很长,因此我想在进行调用时启用微调器,并在调用完成后将其禁用。
So in the method handling the button click (using Command, not code behind) I set the boolean variable to enable the spinner then create a Task
that goes fetches the data and set it to an ObservableCollection<T>
like this 因此,在处理按钮单击的方法中(使用Command,而不是后面的代码),我设置了boolean变量以启用微调器,然后创建一个
Task
,它将获取数据并将其设置为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;
});
}
On completion of the Task
I would like to disable the spinner. 完成
Task
后,我想禁用微调器。
The problem that I am running into is that I am unable to see the spinner during the call. 我遇到的问题是在通话过程中看不到微调框。 The UI is still being blocked, even thou I am using a
Task
to execute the database query. 即使您正在使用
Task
来执行数据库查询,UI仍被阻止。
What am I doing wrong? 我究竟做错了什么?
Your code is running on the UI thead. 您的代码正在UI thead上运行。
You do all your operations in System.Windows.Application.Current.Dispatcher.BeginInvoke(new System.Action(() => { ... }))
so it's natural to block the UI. 您可以在
System.Windows.Application.Current.Dispatcher.BeginInvoke(new System.Action(() => { ... }))
进行所有操作,因此自然会阻塞UI。
You should only call the dispatcher when you really need to do an UI action. 仅在确实需要执行UI操作时才应调用调度程序。
Move var GotData= DBHelper.GetData();
移动
var GotData= DBHelper.GetData();
before the dispatcher. 在调度员之前。
But it'd be better to use the async
/ await
pattern/keywords of C# 5.0 and higher. 但是最好使用C#5.0及更高版本的
async
/ await
模式/关键字。
I always use the bellow code when I have a long running query. 当我有长时间运行的查询时,我总是使用下面的代码。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.