WPF uses a dedicated UI thread to complete interface operations and updates. This thread is associated with a uniqueDispatcherObject, used to schedule work item queues in the FIFO order. Application. Run () is an indirect call to dispatcher. Run.
Dispatcher processes the work item queue through a loop, which is usually "dispatcherframe )". Dispatcher. Run () creates and starts this frame, which is also the final way for application. Run () to start the message loop.
Public sealed class dispatcher
{
[Securitycritical, uipermission (securityaction. linkdemand, unrestricted = true)]
Public static void run ()
{
Pushframe (New dispatcherframe ());
}
}
Dispatcherframe can be nested. You can check the continue attribute to determine whether the loop continues. We can call dispatcher. exitallframes () to terminate all frame loops. Of course, this programming method is not desirable and may cause some unexpected events.
What corresponds to the dispatcher scheduling object isDispatcherobject,
In WPF, most controls inherit from dispatcherobject, and even include application. These are inherited from
The dispatcherobject object has the thread Association feature, which means that only the instance of these objects is created and contains the dispatcher thread (usually the default
Ui thread) to directly update it.
When we try to update a tag from a non-UI thread, we will see the following exception.
Private void button#click (Object sender, routedeventargs E)
{
New thread () => This. label1.content = datetime. Now. tostring (). Start ();
}
According to the restrictions of dispatcherobject, we can use window. Dispatcher. Invoke () to complete the update operation smoothly.
Private void button#click (Object sender, routedeventargs E)
{
New thread () =>
{
This. Dispatcher. Invoke (dispatcherpriority. Normal,
New action () => This. label1.content = datetime. Now. tostring ()));
}). Start ();
}
In other projects (such as class libraries), we can use application. Current. Dispatcher. Invoke (...) to perform the same operation. They all point to the unique object of UI thread dispatcher.
Dispatcher also provides the asynchronous begininvoke version.
Private void button#click (Object sender, routedeventargs E)
{
New thread () =>
{
Application. Current. Dispatcher. begininvoke (dispatcherpriority. Normal,
New action () =>
{
Thread. Sleep (3000 );
This. label1.content = datetime. Now. tostring ();
}));
MessageBox. Show ("Hi! ");
}). Start ();
}
Van
Besides, WPF also provides a type that inherits from freezable, although freezable also indirectly inherits from
Dispatcherobject, but when this type of object changes from the modification state to the frozen state, it becomes a free-threaded object and is not associated with a thread. (Related to freezable
For details, refer to msdn)