使用Async / Await时的WPF ProgressBar用法

时间:2014-10-09 18:54:04

标签: c# wpf

我有一个非常简单的任务,可以加载一些数据:

async Task<List<Invoice>> GetInvoices()
{
    var invoices = await Task.Run(() => db.Invoices.AsNoTracking().ToList());
    return invoices;
}

使用进度条的最佳方法是什么?我不需要加载百分比(虽然这会很有用),我只需要在加载数据的开始和结束时显示/隐藏进度条。有没有办法创建一个完成或完成的方法呢?

我非常喜欢异步/等待,所以请戴上手套!

3 个答案:

答案 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控件的线程。