DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

WPF 4.5 – Part 3 : New Methods of the Dispatcher

Jon Antoine user avatar by
Jon Antoine
·
Aug. 01, 12 · Interview
Like (0)
Save
Tweet
Share
8.11K Views

Join the DZone community and get the full member experience.

Join For Free
dispatcher this is the third part of the serie on the wpf 4.5 new features .

the dispatcher class is maybe one of the most used in wpf when you start doing thing asyncronously. it is the only way to update ui controls from an another thread.

even if it was easy to use, the wpf teams added 13 methods which will ease up this. especially with the new await keyword. in this post we will discover these new methods.

the new ‘classic’ methods

there is some overload which takes as a param a func delegate. where in prior versions, the available methods on the dispatcher were not able to return something (except void) it is now possible.

the new methods of this kind are :

  • invoke(func)
  • invoke(func, dispatcherpriority)
  • invoke(func, dispatcherpriority, cancellationtoken)
  • invoke(func, dispatcherpriority, cancellationtoken, timespan)

prior to wpf 4.5, to return something, this code should have been written:

//the function which returns something (here of type object)
func<object> myreturningobjectfunction = () =>
{//for example only !
    return new object();
};
 
object returnedoject = null;
 
//a mock action to be abble to return the object
action mockaction = () => { returnedoject = myreturningobjectfunction(); };
 
//actually invoke the method
dispatcher.currentdispatcher.invoke(mockaction, null);
 
//here i can use the returned object

now, you can write a more maintanable code by using this one:

public void callingmethod()
{
    object returnedoject = dispatcher.currentdispatcher
        .invoke(myreturningobjectfunction, null);
}
 
//this method can now live alone !
private object myreturningobjectfunction()
{
    //for example only !
    return new object();
}

await-ready !

you surely are aware of the new-born ‘await’ keyword.
the wpf team is too and the dispatcher is now await-ready !

here is the new methods which are await-ready:

  1. invokeasync(action)
  2. invokeasync(action, dispatcherpriority)
  3. invokeasync(action, dispatcherpriority, cancellationtoken)
  4. invokeasync(func)
  5. invokeasync(func, dispatcherpriority)
  6. invokeasync(func, dispatcherpriority, cancellationtoken)

these method returns objects of the dispatcheroperation/dispatcheroperation type.
you can then use the await keyword on it or on its ‘task’ property.
here is an example:

public async void callingmethod()
{
    await dispatcher.currentdispatcher.invokeasync(myreturningobjectfunction);
}

also, you can do some synchronisation and wait for a dispatcher operation to be finished by using the dispatcheroperationwait method on the task. this is an extension method of the taskextensions class (available on system.windows.threading).

dispatcheroperation<object> dispatcheroperation =
 dispatcher.currentdispatcher.invokeasync(myreturningobjectfunction);
 
dispatcheroperation.task.wait();

there is a disclaimer/warning on this last one “calling task.wait will result in a deadlock if the operation is queued on a calling thread. for more information about using a task to perform asynchronous operations, see task parallelism (task parallel library).”

cancellation

finally, you may have noticed the new parameter of type cancellationtoken.
this is part of the .net 4 cancellation framework .
under the hood, the dispatcher operation you start creates a task object which will be regulated by this cancellation token.
if the task has not started, ie. your dispatcher operation has not, then it won’t start. if it has started it won’t be stopped and then continue its execution.

in fact, it’s up to the task’s action to check the cancellation token to stop itself. however, i didn’t find a way to pass the cancellation token to the given action instead of using the same trick i presented on the first paragraph about the returned object. :-(

i didn’t find a scenario in which using the cancellation token is necessary but i think it’s coming from the things necessary to make the async keyword work.

this kind of scenario is a bit hard to reproduce in a demo but i managed to get a working example:

//create a token source
var cts = new cancellationtokensource();
 
//launch the cancel of the token
task.factory.startnew(() => cts.cancel());
 
//launch an operation with priority normal
// this will delay the execution of the following invoke call.
dispatcher.begininvoke(new action(() =>
{
    int i = 0; while (i < 300)
        //update the ui to be sure to block the following
        // action. rendering will occur and takes precedence
    { i++; _countertextblock.text = i.tostring(); }
}), null);
 
 
try
{
    //launch a task with the cancellation token
    dispatcher.invoke(() => { while (true);},
        dispatcherpriority.background, cts.token);
}
catch (operationcanceledexception ex)
{
    //we are here because the token was cancelled
    console.writeline("the operation didn't even start !");
}

bonus

as a bonus you also have two new methods which add nothing special except an easier use :

  1. invoke(action)
  2. invoke(action, dispatcherpriority, cancellationtoken, timespan)

you can also find the dispatcher documenation on msdn .

regards,

Windows Presentation Foundation

Published at DZone with permission of Jon Antoine, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Java Development Trends 2023
  • Memory Debugging: A Deep Level of Insight
  • The 12 Biggest Android App Development Trends in 2023
  • Secrets Management

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: