简体   繁体   中英

Dispatcher and async await in WPF

I am trying to learn asynchronous programming in WPF/C# and I am stuck on asynchronous programming and using Dispatchers. Are they both different or are they or are to be used in the same scenario? I am willing keeping this question short as to not be vague because I understand that I am messing up between a concept and a function in WPF, but not enough to functionally use it correctly.

My doubt arises after I asked a question here, This is my question , I was told to use Dispatcher for this problem and that WPF runs on a single thread and you need to use BeginInvoke , here was where I first heard Dispatcher and before that I just user async and await with Task.Run these 3 keywords only.

But then this article is Asynchronous programming in C# with WPF .

All I need to do is load a few pages into a Grid and this happens at the start of the application (this part I think deals with Dispatcher as it is a part of the UI), and then CRUD to a Database.

You should not use Dispatcher . Instead, you can use await or IProgress<T> to delegate work back to the UI thread.

Eg:

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";
}

If you need to update UI elements with progress updates, then use 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");
}

I will explain in general terms, not exactly.

When you want to execute a method asynchronously, you create a task. This task is performed by an arbitrary thread from the thread pool.

But what if you need to make the method execute in a specific thread?
This is a common task for UI elements - they should always only run on the main thread of the application.

To solve this problem, Dispatchers for threads were created.
Each thread can only have one dispatcher.
It is created the first time you access it.
Using the Thread Dispatcher, you can execute your asynchronous method on this thread.

Invoke - Executes a method synchronously on the Dispatcher thread.
It's like just calling a regular synchronous method.
Execution of the main method (in which Invoke was called) will not continue until the method passed to Invoke is executed.
The thread in which the main method is executed also stops.
Invoke used extremely rarely.

InvokeAsync and BeginInvoke are asynchronous execution.
They differ in small details - I will not go into their explanation now.
These methods return a DispatcherOperation object.
With which you can interact with the task executing your method.
The most common use is BeginInvoke without receiving a DispatcherOperation.

The best way to load data is to create a Model with asynchronous methods (async-await). After loading the data, the ViewModel will receive this data and provide it in its properties. When the ViewModel property changes its value, you need to raise the PropertyChanged event (the ViewModel must necessarily implement INotifyPropertyChanged). In what streams this happens - it does not matter.

UI elements (WPF View) will receive this data through bindings of the ViewModel properties . The mechanism of bindings is designed in such a way that regardless of the thread in which the property has changed, the binding will update the UI element always in their Dispatcher.

With such an implementation, you do not need to worry about the streams in which data is received from the database or other work with data occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM