我有一个非常简单的任务,可以加载一些数据:
async Task<List<Invoice>> GetInvoices()
{
var invoices = await Task.Run(() => db.Invoices.AsNoTracking().ToList());
return invoices;
}
使用进度条的最佳方法是什么?我不需要加载百分比(虽然这会很有用),我只需要在加载数据的开始和结束时显示/隐藏进度条。有没有办法创建一个完成或完成的方法呢?
我非常喜欢异步/等待,所以请戴上手套!
答案 0 :(得分:8)
假设在某个UI事件处理程序中调用了GetInvoices
并且有一个名为ProgressBar
的进度条控件,它非常简单:
private async void OnButton1Click(..)
{
ProgressBar.IsIndeterminate = true;
var result = await GetInvoices();
ProgressBar.IsIndeterminate = false; // Maybe hide it, too
// TODO: Do stuff with result
}
如果您想显示实际进度,请查看Progress<T>
和IProgress<T>
。
答案 1 :(得分:2)
你已经拥有了你需要的东西。这里举例说明一个带有任务并使用await和ContinueWith的简单示例。
using System;
using System.Threading.Tasks;
using System.Diagnostics;
public class Program
{
public static void Main()
{
Task t = new Program().TestTasks();
Console.WriteLine("hello");
t.Wait();
}
public async Task TestTasks()
{
Stopwatch watch = Stopwatch.StartNew();
Console.WriteLine("1." + watch.ElapsedMilliseconds);
// await task
int res = await TestAsync();
Console.WriteLine("2." + watch.ElapsedMilliseconds + " " + res);
// save task and wait on it
Task<int> t = TestAsync();
t.ContinueWith((r) =>
{
Console.WriteLine("4." + watch.ElapsedMilliseconds + " " + r.Result);
});
Console.WriteLine("3." + watch.ElapsedMilliseconds);
t.Wait();
}
public static async Task<int> TestAsync()
{
await Task.Delay(TimeSpan.FromSeconds(2));
return 42;
}
}
打印:
1.0 hello 2.2009 42 3.2009 4.4013 42
注意await如何离开方法并打印&#34;你好&#34;在Main方法中,在(大约)2秒后继续在TestTasks方法中。另一方面,如果我们不等待,当第二次调用TestAsync显示时,立即打印3.然后在2秒后打印4.
考虑到这一点,您可以随意调用方法GetInvoices
,因为您将返回任务。
// Set state of progressbar to indeterminate
List<Invoice> result = await GetInvoices();
// Set state of progressbar to nothing
答案 2 :(得分:0)
您可以执行以下操作:
var task = Task.Run(() => db.Invoices.AsNoTracking().ToList());
//show progress
task.ContinueWith(...CLOSE PROGRESS BAR...);
在实践中,您使用Task.ContinueWith构造来捕获任务的终止并隐藏您之前显示的进度条。
注意:请记住,对来自另一个线程的UI元素进行操作需要Invoke()
调用,因为该调用将实际调用重定向到主线程,这是唯一一个可以在Windows上操作UI控件的线程。