在WPF控件(例如网格)中,我们通常可以设置一个布尔属性来显示控件正在忙着加载数据,而在UI中,这将导致“加载.”。指标。
在使用async方法时,我们只需确保在调用该方法之前调用IsBusy = "true",在调用await之后调用IsBusy="false"即可。
但是,如果我可以多次调用网格加载方法,在第一次调用完成时,即使第二次调用正在进行,它也会关闭繁忙指示器。
有办法解决这个问题吗?我可以设置一个全局计数器来存储请求的数量,并根据这个全局变量的计数来设置指示符的状态,但是这是一种肮脏的方法,如果我的代码中有多个asyn事件,它就不会缩放。
示例场景
在下面的图片中,我可以搜索学生的名字,每一个名字我的服务将得到详细信息(标记等)。并显示在第二个网格中。
当第二个网格正在等待数据时,我想显示一个繁忙的指示器(否则用户可能不知道程序是否在做任何事情)。
输入名称时,调用以下方法:
想象一下,GetStudentResults需要5秒时间(每次调用)。我在0秒输入名字,然后在3秒时输入另一个名字。现在,在5秒,第一个调用返回,它关闭繁忙的指示,而第二个名称的详细信息不被检索。这就是我想要避免的。
private async void SearchName(string name)
{
ResultDisplayGrid.IsBusy = true;
await GetStudentResults();
ResultDisplayGrid.IsBusy = false;
}


发布于 2018-09-07 07:29:42
您将需要使用CancellationTokenSource来获得一个令牌,您可以跟踪该任务是否已被重新输入取消。
private CancellationTokenSource tokenSource;
public async void Search(string name)
{
this.tokenSource?.Cancel();
this.tokenSource = new CancellationTokenSource();
var token = this.tokenSource.Token;
this.IsBusy = true;
try
{
// await for the result from your async method (non void)
var result = await this.GetStudentResults(name, token);
// If it was cancelled by re-entry, just return
if (token.IsCancellationRequested)
{
return;
}
// If not cancelled then stop busy state
this.IsBusy = false;
Console.WriteLine($"{name} {result}");
}
catch (TaskCanceledException ex)
{
// Canceling the task will throw TaskCanceledException so handle it
Trace.WriteLine(ex.Message);
}
}此外,如果将GetStudentResults设置为true,则您的token.IsCancellationRequested应该考虑到令牌,并停止任何背景处理。
https://stackoverflow.com/questions/52214885
复制相似问题