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