Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Async/Await时WPF ProgressBar的使用_C#_Wpf - Fatal编程技术网

C# 使用Async/Await时WPF ProgressBar的使用

C# 使用Async/Await时WPF ProgressBar的使用,c#,wpf,C#,Wpf,我有一个非常简单的任务,加载一些数据,如下所示: async Task<List<Invoice>> GetInvoices() { var invoices = await Task.Run(() => db.Invoices.AsNoTracking().ToList()); return invoices; } 异步任务GetInvoices() { var invoices=wait Task.Run(()=>db.invoices.AsN

我有一个非常简单的任务,加载一些数据,如下所示:

async Task<List<Invoice>> GetInvoices()
{
    var invoices = await Task.Run(() => db.Invoices.AsNoTracking().ToList());
    return invoices;
}
异步任务GetInvoices() { var invoices=wait Task.Run(()=>db.invoices.AsNoTracking().ToList()); 退回发票; } 使用progressbar的最佳方式是什么?我不需要获得加载的百分比(尽管这会很有用),我只需要在加载数据的开始和结束时显示/隐藏progressbar。有没有一种方法可以创建一个完成的或完成的方法


我对async/Wait非常陌生,所以请戴上小手套

您可以执行以下操作:

var task = Task.Run(() => db.Invoices.AsNoTracking().ToList()); 

//show progress

task.ContinueWith(...CLOSE PROGRESS BAR...);
实际上,您可以使用construct捕捉任务的结束,并隐藏以前显示的进度条


注意:请记住,从另一个线程对UI元素执行操作需要调用
Invoke()
call,因为该调用将实际调用重定向到主线程,而主线程是唯一可以在windows上操作UI控件的线程

假设在某个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
}

如果您想显示实际进度,请查看和。

您已经有了所需的。下面是一个简单的示例,其中包含任务和使用wait和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;
    }
}
注意wait是如何离开方法并在Main方法中打印“hello”的,并且在(大约)2秒钟后在TestTasks方法中继续。另一方面,如果我们不等待,如第二次调用TestAsync所示,3。立即打印,2秒后,4。是印刷的

考虑到这一点,您可以使用wait调用您的方法
GetInvoices
,因为您正在返回一个任务

// Set state of progressbar to indeterminate
List<Invoice> result = await GetInvoices();
// Set state of progressbar to nothing
//将progressbar的状态设置为不确定
列表结果=等待获取发票();
//将progressbar的状态设置为“无”

这意味着不应以模式显示ProgressBar?希望这符合OP的要求。@KingKing:为什么不呢?1)在另一个线程上开始计算2)显示对话框3)捕获线程的终止4)调用关闭对话框。我知道
//show progress
是显示progressbar对话框的代码的占位符。因此,如果以模式显示,
任务.ContinueWith
将不会执行。当然,如果在那里创建一个新线程,也没关系。我没有否决这个答案。看来你不明白我的意思。我的意思是我理解代码中的
//show progress
注释是此类代码的占位符
progressBarDialog.ShowDialog()。然后,这将阻止当前线程和
任务。将不会调用ContinueWith
。我认为显示progressbar对话框的代码可以放在
任务之后。ContinueWith
@KingKing:如果您阅读了有关task.Complete的文档,它会说:“创建一个在目标任务完成时异步执行的延续。”因此它会被调用。但是..您正在用wait等待任务,只需在开始时将progressbar的状态设置为Undeterminate,并在等待后停止它。我通常会将回调传递给后台任务/工作进程,它可以用来报告进度,回调会在UI线程上安排进度指示器更新。但是,由于您的任务是一个单独的语句,我不确定您是否有一种方便的方式来表示增量进度。按照@Patrick的建议,最好使用不确定的等待指示器。您应该使用
ToListAsync
异步执行查询,而不是在另一个线程中同步执行查询。
// Set state of progressbar to indeterminate
List<Invoice> result = await GetInvoices();
// Set state of progressbar to nothing