WPF Getting Started Tutorial series four--dispatcher Introduction

Source: Internet
Author: User

I. Introduction of Dispatcher

Microsoft introduced dispatcher in WPF, so what is the main role of this dispatcher?

Whether it is a WinForm application or a WPF application, it is actually a process, a process can contain multiple threads, one of which is the main thread, and the rest is a child thread. In WPF or WinForm applications, the main thread is responsible for receiving input, handling events, drawing the screen and so on, in order to make the main thread timely response to prevent suspended animation, in the development process for some time-consuming operations, more resource-intensive operations, will create one or more sub-threads to complete the operation, such as large data volume of the loop operation, background download. This way, because the UI interface is created by the main thread, the child threads cannot directly update the UI interface maintained by the main thread.

The role of dispatcher is to manage thread work item queues, similar to Message Queuing in Win32, dispatcher intrinsic functions, still invoke traditional Create window classes, create windows, build message pumps, and so on. Dispatcher itself is a singleton pattern, the constructor is private, exposing a static Currentdispatcher method to get the dispatcher of the current thread. For threads, it knows nothing about Dispatcher, Dispatcher internally maintains a static list<dispatcher> _dispatchers, and whenever the Currentdispatcher method is used, It is traversed in this _dispatchers, and if not found, create a new Dispatcher object and add it to the _dispatchers. Dispatcher internally maintains a thread's properties, when creating a dispatcher, the current thread is assigned to the attribute of the thread, and the next time the lookup is traversed, the field is used to match whether the _ The dispatcher of the current thread has been saved in dispatchers.

Ii. the inheritance relationship of dispatcher

In the WPF class hierarchy, most of the focus is derived from the Dispatcherobject class (through other classes). As shown, you can see that the Dispatcherobject virtual class is located just below the Object and between the hierarchies of most WPF classes. To understand the relationship between them, refer to this class of inheritance diagram:

Some of the explanations:

1) System.Object class: We all know in. NET all types of base classes, dispatcherobject inherit from it, so it is the base class of WPF.

2) System.Windows.Threading.DispatcherObject class: See Most of the controls used in WPF and other classes are mostly inherited Dispatcherobject classes, which provide the basic constructs for handling concurrency and threading.

3) System.Windows.DependencyObject class: Support for dependency property hosting in WPF and attached property hosting support, represents an object that participates in a dependency property system.

4) System.Windows.Media.Visual class: Provides support for rendering in WPF, including hit testing, coordinate transformations, bounding box calculations, and so on.

5) System.Windows.UIElement class: UIElement is the base class for WPF core-level implementations, which are the visual appearance in Windows Presentation Foundation (WPF) and the majority of objects that can handle basic input. Base class.

6) System.Windows.FrameworkElement class: Provides WPF framework-level property sets, event sets, and method sets for Windows Presentation Foundation (WPF) elements. This class represents the accompanying WPF framework-level implementation, which is built on the WPF core-level API defined by UIElement.

7) System.Windows.Controls.Control class: Represents the base class for user interface (UI) elements that use ControlTemplate to define their appearance.

8) System.Windows.Controls.ContentControl class: Indicates that no content of any type represents a single control.

Most of WPF's controls, and also the windows themselves, are inherited from ContentControl.

The ContentControl family contains controls

Button

ButtonBase

CheckBox

ComboBoxItem

ContentControl

Frame

Gridviewcolumnheader

Groupitem

Label

ListBoxItem

ListViewItem

NavigationWindow

RadioButton

RepeatButton

ScrollViewer

StatusBarItem

ToggleButton

ToolTip

UserControl

Window

9) System.Windows.Controls.ItemsControl class: Represents a control that can be used to provide a collection of items.

A control that itemscontrol the contents of an entry collection

Features: A. are derived from ItemsControl

B. Content property is items or ItemsSource

C. Each itemscontrol should have its own entry container (item Container).

The ItemsControl family contains controls

Menu

Menubase

ContextMenu

ComboBox

ItemsControl

ListBox

Listview

TabControl

Treeview

Selector

StatusBar

System.Windows.Controls.Panel class: Provides a base class for all Panel elements. Use the Panel element to locate and arrange child objects in a Windows Presentation Foundation (WPF) application.

System.Windows.Sharps.Sharp class: Provides a base class for shape elements such as Ellipse, Polygon, and Rectangle.

Three, into the dispatcher

When all WPF applications are started, two important threads are loaded: one for rendering the user interface and the other for managing the user interface. The rendering thread is a hidden thread that runs in the background, so the only thread you typically face is the UI thread. WPF requires that most of its objects be associated with the UI thread. This is called thread affinity, meaning that a WPF object is used only on the thread that created it. Using it on other threads causes a run-time exception to be thrown. The role of the UI thread is to receive input, handle events, draw screens, and run application code.

Most of the controls in WPF inherit from Dispatcherobject, even including application. These objects that inherit from Dispatcherobject have thread affinity characteristics, which means that only those object instances are created, and that the thread that contains the Dispatcher (usually the default UI thread) can update it directly.

The Dispatcherobject class has two primary responsibilities: providing access to the current Dispatcher associated with the object, and providing methods to check (CheckAccess) and verify (verifyaccess) whether a thread has access to the object (derived from Dispatcherobject). The difference between CheckAccess and verifyaccess is that CheckAccess returns a Boolean value that indicates whether the current thread can use the object, and VerifyAccess throws an exception if the threads do not have access to the object. By providing these basic features, all WPF objects support the ability to determine whether they can be used on specific threads (especially UI threads). Such as.

In WPF, Dispatcherobject can only be accessed through the Dispatcher associated with it. For example, a background thread cannot update the contents of a label created by the UI thread.

So how do you update the object information created by the UI thread? Dispatcher provides two methods, invoke and BeginInvoke, and these two methods also have multiple overloads of different parameters. where invoke internally or BeginInvoke is called, a typical BeginInvoke parameter is as follows:

   

Invoke is a synchronous operation, and BeginInvoke is an asynchronous operation.       These two operations are added to the Dispatcher queue by the specified dispatcherpriority. DispatcherPriority defines a number of priorities, which can be divided into foreground priority and background priority, where the front desk includes loaded~send and the background includes background~input. The remaining priority levels are idle, except for invalid and inactive. The dividing line between the foreground priority and the background priority is based on input, where input refers to keyboard input and mouse movement, clicks, and so on.

Dispatchpriority Priority level

Priority level

Description

Invalid

This is an invalid priority.

Inactive

Work items are queued but not processed.

Systemidle

Work items are dispatched to the UI thread only when the system is idle. This is the lowest priority of the project that is actually being processed.

Applicationidle

Work items are dispatched to the UI thread only when the application itself is idle.

Contextidle

Work items are dispatched to the UI thread only after the higher-priority work items are processed.

Background

Work items are dispatched to the UI thread after all layout, rendering, and input items have been processed.

Input

The work item is dispatched to the UI thread with the same priority as the user input.

Loaded

The work item is dispatched to the UI thread after all layout and rendering are complete.

Render

Dispatches work items to the UI thread at the same priority as the rendering engine.

DataBind

Dispatches work items to the UI thread with the same priority as data binding.

Normal

Dispatches work items to the UI thread at normal priority. This is the priority when scheduling most application work items.

Send

Dispatches a work item to the UI thread at the highest priority level.

Iv. use of Dispatcher

Let's use an example to see how to properly update an object created by the UI thread from a non-UI thread.

1, the wrong way to update

XAML Code :

<window x:class= "WPFAPP1.WINDOWTHD"        xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"        Title= "WINDOWTHD" height= "width=" >    <Grid>         <StackPanel>            <label x:name= " Lblhello "> Welcome you to the world of WPF!</label>            <button name=" BTNTHD "click=" Btnthd_click "> Multithreaded synchronous calls </button >            <button name= "Btnappbegininvoke" click= "Btnappbegininvoke_click" >begininvoke Asynchronous call </Button>        </StackPanel>    

Background code:

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading;using System.threading.tasks;using system.windows;using system.windows.controls;using System.Windows.Data;using System.windows.documents;using system.windows.input;using system.windows.media;using System.Windows.Media.Imaging ; using System.Windows.Shapes; namespace wpfapp1{//<summary>//    Windowthd.xaml Interactive logic///    </summary> public    Partial Class Windowthd:window    {public        windowthd ()        {            InitializeComponent ();              }     private void Modifyui ()    {        //simulate some work in progress        Thread.Sleep (Timespan.fromseconds (2));        Lblhello.content = "Welcome you to the world of WPF, Dispatcher";    }     private void Btnthd_click (object sender, RoutedEventArgs e)    {        thread thread = new Thread (Modifyui);        Thread. Start ();}}     }


Error:

2, the correct way to update, from the above example we have seen from the child thread directly update the UI thread created object, will report an error. How should it be modified? Let's change the code above to see what it will look like.

private void Modifyui ()    {        //simulate some work in progress        Thread.Sleep (Timespan.fromseconds (2));        Lblhello.content = "Welcome to the world of WPF, Dispatcher";        This. Dispatcher.invoke (Dispatcherpriority.normal, (ThreadStart) delegate ()        {            lblhello.content = "Welcome to the world of WPF, Dispatche  Sync Method!! ";        });}


Of course the dispatcher class also provides the BeginInvoke method, and we can also use the following code to complete the update of the content of the lable.

private void Btnappbegininvoke_click (object sender, RoutedEventArgs e)    {               new Thread (() =        {            Application.Current.Dispatcher.BeginInvoke (Dispatcherpriority.normal,                new Action () =                {                    Thread.Sleep (Timespan.fromseconds (2));                    This.lblHello.Content = "Welcome to the world of WPF, Dispatche async Method!! "+ DateTime.Now.ToString ();                }))        . Start ();    

V. Summary

In WPF, all WPF objects derive from Dispatcherobject,dispatcherobject exposes the dispatcher property used to get the dispatcher that corresponds to the object thread being created. The Dispatcherobject object can only be accessed by the thread that created it, and other thread modifications dispatcherobject need to get the corresponding dispatcher, invoke invoke or BeginInvoke to go into the task. Some of the design ideas of dispatcher, including Invoke and BeginInvoke, are always present from the WinForm era, and only dispatcher are used to encapsulate these thread-level operations.

WPF Getting Started Tutorial series four--dispatcher Introduction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.