Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Futher to what H.B. and dowhilefor have said, here is a sample that shows starting a task on a background thread using BackgroundWorker with one Button and ending it with another Button, note the use of Dispatcher.BeginInvoke:</p> <p><strong>XAML</strong></p> <pre><code>&lt;Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="80" Width="640" FontSize="16"&gt; &lt;DockPanel VerticalAlignment="Center"&gt; &lt;Button Margin="10,0" x:Name="runButton" DockPanel.Dock="Left" Click="RunButtonClickHandler"&gt;Run&lt;/Button&gt; &lt;Button Margin="10,0" x:Name="stopButton" DockPanel.Dock="Left" Click="StopButtonClickHandler"&gt;Stop&lt;/Button&gt; &lt;TextBlock Margin="10,0"&gt;The Time Is Now:&lt;/TextBlock&gt; &lt;TextBlock x:Name="timeTextBlock" Margin="10,0" /&gt; &lt;/DockPanel&gt; &lt;/Window&gt; </code></pre> <p><strong>Code Behind</strong></p> <pre><code>using System; using System.ComponentModel; using System.Threading; using System.Windows; using System.Windows.Threading; namespace WpfApplication1 { /// &lt;summary&gt; /// Interaction logic for MainWindow.xaml /// &lt;/summary&gt; public partial class MainWindow : Window { private BackgroundWorker _worker; public MainWindow() { InitializeComponent(); } private void RunButtonClickHandler(object sender, RoutedEventArgs e) { _worker = new BackgroundWorker {WorkerSupportsCancellation = true}; _worker.DoWork += BackgroundWorkerTask; _worker.RunWorkerAsync(); } private void StopButtonClickHandler(object sender, RoutedEventArgs e) { if (_worker != null &amp;&amp; _worker.IsBusy) _worker.CancelAsync(); } private void BackgroundWorkerTask(object sender, DoWorkEventArgs e) { // this runs on the BackgroundWorker thread. while (_worker.CancellationPending == false) { Thread.Sleep(500); // You have to use the Dispatcher to transfer the effects of // work done in the worker thread back onto the UI thread. Dispatcher.BeginInvoke(new Action(UpdateTime), DispatcherPriority.Normal, null); } } private void UpdateTime() { // Dispatcher runs this on the UI thread. timeTextBlock.Text = DateTime.Now.ToString(); } } } </code></pre> <p><strong>EDIT - A Little More Explanation</strong></p> <p><em>RunButtonClickHandler</em></p> <p>Creates and initializes a <code>BackgroundWorker</code> so that it supports cancellation.<br> Attaches a <code>DoWorkEventHandler</code> to the <code>DoWork</code> event, i.e. <code>BackgroundWorkerTask</code>.<br> Starts excecution of the background operation with the call to <code>RunWorkerAsync</code>, i.e. creates a new thread (actually it uses a thread from the thread pool) and runs the code in <code>BackgroundWorkerTask</code> on that thread.</p> <p><em>BackgroundWorkerTask</em></p> <p>If you want to do work that would otherwise cause the UI to freeze when running on the main UI thread (e.g. search for undiscovered prime numbers) then you do it here in the background thread.</p> <p><em>UpdateTime</em></p> <p>All WPF <code>Control</code>s inherit from <code>DispatcherObject</code> and are associated with a <code>Dispatcher</code> which manages the execution of work done in the UI's single thread. If you need to do work such as setting the text of a <code>TextBlock</code>, you can't do it from the background thread, trying to do so will cause an exception to be thrown. <code>UpdateTime</code> is queued back onto the UI thread by the <code>Dispatcher</code> when <code>Dispatcher.BeginInvoke</code> is called from <code>BackgroundWorkerTask</code>. This way you can get the results of work done in the background before cancelling the background threads execution.</p> <p><em>StopButtonClickHandler</em></p> <p>Changes <code>_worker.CancellationPending</code> to true with the call to <code>CancelAsync</code> causing the while loop to exit and thus for execution to leave the <code>BackgroundWorkerTask</code> event handler.</p> <p>In short, you can do work in two places, either in <code>BackgroundWorkerTask</code> or in <code>UpdateTime</code>, but you can only carry out changes to UI elements from <code>UpdateTime</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload