[英]Dispatcher and async await in WPF
我正在尝试在 WPF/C# 中学习异步编程,但我一直坚持异步编程和使用 Dispatchers。 它们是不同的还是它们或将在同一场景中使用? 我愿意保持这个问题简短,以免含糊不清,因为我知道我在 WPF 中混淆了一个概念和一个函数,但还不足以在功能上正确使用它。
我在这里问了一个问题后出现了我的疑问, 这是我的问题,有人告诉我使用Dispatcher
解决这个问题,WPF 在单线程上运行,你需要使用BeginInvoke
,这是我第一次听到Dispatcher
,在此之前我只是用户 async 并等待Task.Run
仅使用这 3 个关键字。
但是这篇文章是使用 WPF 在 C# 中进行异步编程。
我需要做的就是将几页加载到Grid
,这发生在应用程序的开始(我认为这部分处理Dispatcher
因为它是 UI 的一部分),然后 CRUD 到数据库。
你不应该使用Dispatcher
。 相反,您可以使用await
或IProgress<T>
将工作委托回 UI 线程。
例如:
private async void b1_Click(object sender, RoutedEventArgs e)
{
// We are starting on the UI thread here.
txtb1.Text = "";
var watch = System.Diagnostics.Stopwatch.StartNew();
await writeintxtbx();
// After the await completes, we return to the UI thread because await captured the UI context.
watch.Stop();
var elapsedtm = watch.ElapsedMilliseconds;
// Since we're on the UI thread, we can update UI elements.
txtb1.Text += $"TOTAL TIME {elapsedtm} \n\n\n";
}
如果您需要使用进度更新来更新 UI 元素,请使用IProgress<T>
:
private async Task writeintxtbx()
{
var progress = new Progress<string>(x => txtb1.Text += x);
await Task.Run(() => Task1(progress));
await Task.Run(() => Task2(progress));
}
private void Task1(IProgress<string> progress)
{
progress?.Report($"Task 01 Done \n\n");
}
private void Task2()
{
progress?.Report($"Task 2 done \n\n");
}
我会笼统地解释,而不是完全解释。
当你想异步执行一个方法时,你创建了一个任务。 该任务由线程池中的任意线程执行。
但是,如果您需要使该方法在特定线程中执行怎么办?
这是 UI 元素的常见任务 - 它们应该始终只在应用程序的主线程上运行。
为了解决这个问题,创建了线程调度程序。
每个线程只能有一个调度程序。
它是在您第一次访问时创建的。
使用线程调度器,您可以在该线程上执行异步方法。
Invoke - 在 Dispatcher 线程上同步执行一个方法。
这就像调用一个常规的同步方法。
在执行传递给 Invoke 的方法之前,不会继续执行 main 方法(在其中调用 Invoke)。
执行 main 方法的线程也会停止。
极少使用的调用。
InvokeAsync 和 BeginInvoke 是异步执行。
他们在小细节上有所不同——我现在不会去解释他们。
这些方法返回一个 DispatcherOperation 对象。
您可以使用它与执行您的方法的任务进行交互。
最常见的用途是 BeginInvoke 而不接收 DispatcherOperation。
加载数据的最佳方式是使用异步方法(async-await)创建模型。 加载数据后,ViewModel 将接收此数据并在其属性中提供它。 当 ViewModel 属性更改其值时,您需要引发 PropertyChanged 事件(ViewModel 必须实现 INotifyPropertyChanged)。 在什么流中会发生这种情况 - 没关系。
UI 元素(WPF 视图)将通过 ViewModel 属性的绑定接收此数据。 绑定机制的设计方式是,无论属性在哪个线程中发生更改,绑定都将始终在其 Dispatcher 中更新 UI 元素。
通过这样的实现,您无需担心从数据库接收数据的流或其他处理数据的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.