Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

Essential Silverlight and WPF Skills: The UI Thread, Dispatchers, Background Workers and Async Network Programming

Pete Brown - 23 April 2010

I'm starting a occasional series of postings on top things every Silverlight and WPF developer should know. Originally, I was going to make this a top-10 style list, but I'll keep that for my presentations, and instead expand on it here, with one topic per post.

This one is about threading in Silverlight.

Ok, that subject sounds like a lot, but it's all pretty closely related.

Both Silverlight and WPF have the concept of a UI thread. Whenever you tie that thread up, you make your application unresponsive. In Silverlight, if you're on a page with other plug-ins, you make all the plug-ins unresponsive. (It's actually per-process, but most modern browsers separate processes by tabs)

Async Network Calls

In order to keep from tying up the UI thread, you have to perform long-running processes on another thread. Often, but not always, those processes are network calls. In Silverlight, all network calls are async with no provision to handle them any other way. This lets you off the hook threading-wise, but requires that you understand how to chain those calls, and how to deal with libraries that have IAsyncResult callbacks that return on different threads.

TestServiceClient client = new TestServiceClient();
client.DoSomethingSlowCompleted += (s, ea) =>
    {
        // do something with the results here
        Debug.WriteLine(ea.Result);
    };

client.DoSomethingSlowAsync();

Background Worker

For other processes, the BackgroundWorker is a great, simple, way to do some background work while reporting progress to the UI. It takes all the dispatching work away, so you can feel free to manipulate the UI from the ProgressChanged and RunWorkerCompleted events. Do not touch the UI from the DoWork event, as that is actually running on a separate thread.

private BackgroundWorker _worker = new BackgroundWorker();
private void RunLongProcess()
{
    _worker.WorkerReportsProgress = true;

    ProgressBar.Minimum = 0;
    ProgressBar.Maximum = 100;

    _worker.DoWork += (s, e) =>
        {
            for (int i = 0; i < 100; i++)
            {
                // simulate long-running work
                System.Threading.Thread.Sleep(500);
                ((BackgroundWorker)s).ReportProgress(i+1);
            }

        };

    _worker.ProgressChanged += (s, e) =>
        {
            // this is on the UI thread, so you can
            // update UI from here.
            ProgressBar.Value = e.ProgressPercentage;
        };

    _worker.RunWorkerCompleted += (s, e) =>
        {
            // clean up after your stuff, yes, you can touch UI here.                
        };

    _worker.RunWorkerAsync();
        
}

Of course, knowing how to set up event handlers using lambda expressions is always helpful :)

Dispatcher

Sometimes, you spin off a thread of your own, or you have to deal with some of the crufty stacks where the callbacks come back on a different thread from the one that created the call. In those cases, you need to use a dispatcher to make a call back to the UI thread.

If the code is on a page, you can call the dispatcher property and pass it a function to execute (yes, more lambda in this example).

private void UpdateUI()
{
    Dispatcher.BeginInvoke(() =>
        {
            ProgressBar.Value = 50;
        });
}

But, if the code is in some sort of non-UI class, it gets more complex. You can do it this way, using a dummy control (like we did in Silverlight 2):

TextBlock _dispatcherObject = new TextBlock();
private void UpdateUINasty() // avoid this approach unless it's all you've got
{
    _dispatcherObject.Dispatcher.BeginInvoke(() =>
        {
            SomePage.ProgressBar.Value = 50;
        });
}

This example assumes the object itself was created on the UI thread. The better way is to use the Deployment object:

private void UpdateUINotSoNasty()
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        SomePage.ProgressBar.Value = 50;
    });
}

That's better. Definitely the recommended approach for recent versions of Silverlight, including Windows Phone 7.

Timers

What about when you need to run something on a timer? The normal timer classes require manual dispatching to do any UI updates. However, Silverlight and WPF both have the DispatcherTimer class that handles all that for you.

private void StartTimer()
{
    DispatcherTimer timer = new DispatcherTimer();

    timer.Tick += (s, e) =>
        {
            // do some very quick work here

            // update the UI
            StatusText.Text = DateTime.Now.Second.ToString();
        };

    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Start();
}

Of course, realize that what you're doing here is interrupting the UI thread, not really running anything on a separate thread. It's not suitable for anything long-running and cpu-intensive, but rather something where you need to execute on a regular interval. Clock UI updates are a perfect example.

Threads

In general, I discourage folks from spinning off real threads. Very few people understand how to efficiently work with threads, so even if you're a threading genius, the person coming in after you probably isn't. In most cases, the Background Worker will provide you with what you need.

Silverlight doesn't yet have it, but the Parallel Tasking support built into .NET 4 can really help you out should you really need to do more than two things at once. Definitely check it out.

Conclusion

Threading in Silverlight and WPF is a little trickier than some other technologies, because you have to worry about the UI thread. My intention here was to both inform you that this trickiness exists, and then show some ways of dealing with it.

         
posted by Pete Brown on Friday, April 23, 2010
filed under:          

41 comments for “Essential Silverlight and WPF Skills: The UI Thread, Dispatchers, Background Workers and Async Network Programming”

  1. Petesays:
    @Clint

    I really try and get folks new to SL/WPF to stay away from "real" threading, that includes ThreadPool.

    If you're in WPF, you can do more with the parallel extensions in most cases. I'd recommend looking at that before even thinking about custom threads. As we get more cores, it's going to be more and more important to just tell the CPU that we need to do something in parallel and let it figure out how many threads can be effectivly used on the machine.

    If you really know threads enough to handle all the "other" stuff that comes along with them, like cancellation, updating shared data etc. then go for it. Otherwise, I strongly recommend the other approaches.

    That said, I use a single separate thread in the Silverlight C64 emulator precisely because I do know why it's there and how to manage it :)

    Pete
  2. Jonahsays:
    It's kind of misleading in your Dispatcher section to say "In those cases, you need to use a dispatcher to make a call back to the UI thread."

    You don't really *need* Dispatcher, you just need to marshal your call back to the UI thread and the Dispatcher is one way to do that. I find SynchronizationContext just as easy to use as Dispatcher and SynchronizationContext has the added benefit of being unit testable without relying on the existence of a DispatcherObject somewhere in the current AppDomain. Unit testing ViewModels that use Dispatcher is problematic at best. Caveat: I mostly work in WPF, so I can't comment on Deployment.Current.

    Otherwise, great article. Strategies for moving work off/on the UI thread is a skill that more devs should understand.

    Cheers!
  3. Dennysays:
    Yeah, i have used the backgound worker in many many apps....
    i use it in services and in winforms apps all the time.

    and yeah if you do not unerstand threading it can be a tricky mess to manage and make it really stable.
    if you can avoid it then do.

    if you really need to then make sure you know what it's doing.
  4. Bart Czernickisays:
    @Pete,

    I will also add that the Dispatcher object is in the UI class for bot Silverlight/WPF. Therefore, when creating assemblies using this technique you will need to reference the System.Windows.UI (I think assembly) just to do Dispatcher. This is why SynchronizationContext is best practice for most scenarios.

    Dispatcher has one less line of code that is why its always seen in blogs/articles. No need for this:
    SynchrnizationContext syncContext = SynchronizationContext.Current;

    -- Bart Czernicki
  5. Carstensays:
    Hi,

    sure you are right when saying "don't use threads unless you know how" - but I would put it rather: "learn how to use threads if you don't allready before using those" instead.
    No use hiding from conurency these days - embrace and learn this stuff - sooner or later you have to and the TPL, parallel LINQ, etc. won't do anything for you if you don't understand the basic problems.

    BTW: if you don't allready have, take a look at F# that comes with very powerful tools to help you get around some of the problemes with Sync.context etc. you mentioned (Async.SwitchToContext with a closure on the calling Sync.context comes to mind ;) )

    Best regards
  6. AcrodoBomsays:
    Fajna stronka lecz dla polepszenia skutecznosci i reklamy zapraszam do skorzystania z naszej oferty np: [url=http://www.cyberpozycja.pl]Pozycjonowanie stron www[/url] na pewno jestesmy konkurencyjni.
  7. cowRIOsays:
    [b][url=http://www.utrechttandarts.nl/tandartsen/tandartspraktijk-galgenwaard]tandartspraktijk galgenwaard[/url][/b]
    [b][url=http://www.utrechttandarts.nl/tandartsen/tandartspraktijk-staalwijk]staalwijk[/url][/b]
    [b][url=http://www.utrechttandarts.nl/tandartsen/tandartspraktijk-staalwijk]tandartspraktijk staalwijk[/url][/b]
  8. dotNet Followersays:
    Hello!
    Thank you for useful and very detailed post. <a href="http://dotnetfollower.com/wordpress/2011/07/silverlight-for-windows-phone-7-how-to-check-if-the-current-thread-is-ui-one/">Here</a> a couple of words about Dispatcher.CheckAccess().

    Thank you!
  9. Nik Kokkinossays:
    Hallo Pete,

    I found your article , when I was searching for thoughts and solurtions around threads and the Backgroundworker class for Silverlight. I want to express my Problem that I have and if you or an other guy who follows the article can help me to find a solution.
    So my Use Case is as follows:
    - The Application is able to export Framework Elements as Pdf file, using the OpenDialog class . Its page on the Pdf file is a rendered Image of each Framework Element. To do that I use the Telerik Function for exporting to Pdf. This function has the following signature: void Export(Raddocument document, Filestream stream). In this function the parameter document is the generated Pdf document and stream is the Filestream from the opendialog class.
    - When the stream is written to the Hard disk after the User hits the Ok button in the Open Dialog the UI Window of my Silverlight application freezes for a while ( the time it needs for writing the file on the disk) .
    - I tried to use according to your Blog article the Background calss and the Dispatcher , but I got Security exceptions...
    - What can I do , so that the time it needs for the Stream to be written on the Disk , an indicator can inform the user with update progress without freezing ?
  10. Georgesays:
    Interesting Thread!!! Thank you!
    I wonder how if this can solve issue: I get data (a lot) from DB from a domain context (ria services, EF) and I wait, and wait, and wait, and even the busy control blocks.
    Does anyone know how to make a request for RIA services with background worker (or any other solutions, smarter then the given idea).
    Thank you for all who will try!
    Thanks fo Pete for all the knowledge!
  11. Marksays:
    Pete - If I call a WCF service from a backgroundworker - where should the callback code be placed? In the _doWork event handler? When I do that it seems the thread never returns and the runworkercompleted event never gets tripped.

    Thanks
    Mark
  12. Petesays:
    @Mark

    I'm not sure what you mean by where it should be placed. It's just a method, place it in your code and let Silverlight call it. If you're doing it as a lambda, you could define it in the dowork handler if you want, but try with it as a regular method first.


    ...Dammit. I see two spam messages up top that I missed. I hate it when those sneak through. The comment management system in this version of umbraco is not good for old stuff.

    Pete
  13. Marksays:
    Thanks Pete - Turns out my backgroundworker was completing and firing the runworkercompleted event *before* the WCF service call returned. So a better question is when the service callback is fired, what thread is that on: the background thread that made the service call or the main UI thread? The behavior I'm seeing is that the background thread may be long gone by the time the service calls back. If that's true, then even though we call a service on a backgroundthread, the service callback should have access to page variables and UI Elements. Am I thinking straight?

    Mark

  14. Saurabhsays:
    Hi Pete,

    Thanx for the nice article.

    I am using these things in my silverlight application but I am stuck some where.

    I have a CommonSilverlight Class Library project which is used by difference silveright projects, and the CommonSilverlight Class library doesn't know whether the calling method is coming from UI Thread or Background Thread and in CommonSilverlight Class library we are calling some javascript method which is returning XML from server, If it comes from UI Thread then its working fine but if it comes from Background thread then there is a cross thread exception, we can not use Dispatcher.BeginInvoke method because it is a async method and method doesn't return me any xml because it fires after current method execution. we can not use SyncronizationContext here because SynchronizationContext must be declared in UI Thread.

    Do you have any other option to fix this issue.

    Kind Regards,
    Saurabh Kumar
  15. Vikasasays:
    Как жизнь бродяги

    мне интересно Пасхальные квиллинг поделки. Пасхальное яйцо. Мастер класс с пошаговым фото можно посмотреть что-то тут : http://persona-rs.com/2199-pashalnye-kvilling-podelki-pashalnoe-yayco-master-klass-s-poshagovym-foto.html

    Всем спасибо за помошь
  16. SearchMaksZsays:
    Просьба к администраторам форума не удалять данный пост ну или по крайней мере перенести его в более подходящую категорию.
    Просим помощи в распространение информации о похищении ребенка.

    Администраторы, ПРИНОШУ СВОИ ИСКРЕННИЕ ИЗВИНЕНИЯ, к нашей беде откликнулось много людей помогающих нам в распространении информации, в связи с этим были случаи размещения одинаковой информации на форумах и в группах, но просить людей проверять информации перед её размещением были бы верх нашей наглости. Не сочтите данное действие за спам. Спасибо многим из Вас за понимание.
    ******************************************************************
    Request to the forum administrators do not delete this post well, or at least move it to a more appropriate category.
    Please help us spread information about the kidnapping.

    Administrators offer my sincere apologies to our trouble Many people responded to help us in disseminating information concerning the cases were placing the same information in the forums and groups, but ask people to check the information before it is made public would be top of our impudence. Do not consider this action as spam. Thanks to many of you for your understanding.
    ******************************************************************

    Похищен Максимов Александр Евгеньевич, 10 сентября 2006 года рождения, проживал с отцом Максимовым Евгением Александровичем в городе Тирасполь, Молдова.

    29 мая 2014 года ребенок был похищен из спортивной секции в городе Тирасполь, похищен был так называемой биологической "матерью" ребенка Доага (Максимова) Кристина Федоровна, 19 октября 1984 г.р., которая в 2010 году из за психического состояния и регулярных действий ставивших жизнь ребенка под угрозу была лишена родительских прав. С 2010 года по 29 мая 2014 никакого участия в жизни ребенка не принимала, не приходила, не интересовалась, не занималась воспитанием и содержанием ребенка, её судьба была не известна, кроме того, что она занималась проституцией в Турции.

    С 29 мая 2014 года по настоящее время местонахождение ребенка не известно, не известно даже в какой стране она с ребенком находится. Похищен в городе Тирасполь, Приднестровье, вывезен в Республику Молдова. На настоящий момент пытаются незаконно сделать Молдавское гражданство и Молдавский паспорт как самой Доаге (Максимовой) Кристине Федоровне, так и детям, при том, что у Доаги Кристины уже есть два гражданства, это России и Украины, у детей гражданство России. Собирается (либо уже выехала) в Российскую федерацию, в частности может выехать в город Калуга либо в город Обнинск (Калужскую или Московскую область).

    Правоохранительными органами гражданка Максимова (Девичья Доага) Кристина Федоровна объявлена в официальный розыск, возбужденно розыскное дело в отношении её и в отношении ребенка.
    На сегодняшний день в отношении её уже возбужденно уголовное дело.

    Страница похищенного ребенка ( maksimovgenya . ru ) - http://maksimovgenya.ru
    Группа в Одноклассниках - http://ok.ru/maksimovsasha
    Группу которую пытались удалить - http://ok.ru/propalrebe

    На настоящий момент дети не посещают учебные заведения, грубо нарушаются все возможные права ребенка, Просим у Вас помощи в определении место нахождения несовершеннолетнего ребенка, ведь дети должны учиться, должны посещать учебные заведения.

    В Генеральную Прокуратуру, в МВД, в СК, Министерства образования, Юстиции, и т.д. и т.п. вся информация направлена вместе с со всеми копиями документов.

    ******************************************************************

    Kidnapped Maksimov Alexander E., September 10, 2006 birth, lived with his father Eugene A. Maximov in Tiraspol, Moldova.

    May 29, 2014 the child was abducted from the sports section in Tiraspol, was kidnapped by the so-called biological "mother" of the child Doaga (Maximov) Christina F., born October 19, 1984, which in 2010 due to mental status and regular actions put child's life in jeopardy was deprived of parental rights. From 2010 to May 29, 2014 no part in the child's life did not take, did not come, not interested, not involved in the education and maintenance of the child, her fate was not known, except that she was engaged in prostitution in Turkey.

    From May 29 2014 to the present whereabouts of the child does not know, does not even know what country she is with child. Kidnapped in the city of Tiraspol, Transnistria, is taken out in the Republic of Moldova. At the moment, trying to illegally make Moldovan citizenship and Moldovan passport as most Doage (Maximova) Christine Fedorovna and children, despite the fact that Christina Doagi already have dual citizenship, it is Russia and Ukraine, the children Russian citizenship. Going to (or have already left) in the Russian Federation, in particular, can go to the city of Kaluga or Obninsk (Kaluga and Moscow region).

    Law enforcement agencies citizen Maximova (Maiden Doaga) Christina F. announced in the official search, excitedly search case against her and the child.
    To date, in relation to its already a criminal case.

    Page abducted child ( maksimovgenya . ru ) - http://maksimovgenya.ru
    Group at classmates - http://ok.ru/maksimovsasha
    Group which tried to remove - http://ok.ru/propalrebe

    At present, children are not attending schools are grossly violated all possible rights of the child, ask for your help in determining the location of a minor child, because children need to learn, need to attend school.

    Attorney General's Office, the Ministry of Interior, in the UK, the Ministry of Education, Justice, etc. etc. All information filed with all copies of the documents.
  17. AnimeErsays:
    Ищу вельми сыздавна где посмотреть, однако не могу встречать здесь http://uvtek.ru/naruto-novye-serii/naruto-film-pyatyj-2008 Наруто однако в полной версии
    а чень требуется прям ваще нев моготу, уже постоянно сайты облазила, однако не смогла найти где посмотреть вот это http://uvtek.ru/fentezi/shingeki-no-bahamut-genesis-yarost-bagamuta-genezis Shingeki no Bahamut: Genesis / Ярость Багамута: Генезис нужно в лучшем качестсве
    есть ли у кого-нибудь какая нибудь инфа где найти вот это http://uvtek.ru/novye-anime/epokha-doblesti-sengoku-musou-sp-sanada-no-shou-1 Эпоха Доблести / Sengoku Musou SP: Sanada no Shou или это Heroic Age Ищу в другом варианте
    источники можете указывать любые и пожалуйста списком что желание дозволено было скопировать и воззриться сообразно порядку, а то беспричинно замучаюсь
    Коль не сложно посоветуйте что-нибудь ещё своё
  18. Williamdeptsays:
    возьми сейчас набери в яндексе или гугле ВИДЕОЧАТ БАБНИК если хочешь пообщаться с видео с девушками топлесс

    [url=http://babnik.com][img]http://babnik.com/templates/babnik/english/images/logo-big-freevideochat.png[/img][/url]
    [url=http://babnik.com][img]http://babnik.com/live/cache/templates/galleries/managers/1/webmaster_banner_6/16344775b4a2f71e42ff60dc9472c472.png[/img][/url]

    [url=http://babnik.com] смотреть бесплатно секс видео чаты[/url]
  19. Williamdeptsays:
    набери прямо сейчас например в гугле ВИДЕОЧАТ БАБНИК КОМ если сейчас хочешь пообщаться с девушками топлесс

    [url=http://babnik.com][img]http://babnik.com/templates/babnik/english/images/logo-big-freevideochat.png[/img][/url]
    [url=http://babnik.com][img]http://babnik.com/live/cache/templates/galleries/managers/1/webmaster_banner_6/16344775b4a2f71e42ff60dc9472c472.png[/img][/url]

    [url=http://babnik.com] секс видео через чат[/url]
  20. sananaksays:
    allsites.ge - georgian sites directory
    [url=http://allsites.ge/]saitebi[/url]
    [url=http://allsites.ge/]qartuli saitebi[/url]
    [url=http://allsites.ge/]saitebis katalogi[/url]
    [url=http://allsites.ge/]qartuli[/url]
    [url=http://allsites.ge/]qartulad natargmni filmebi[/url]
    [url=http://allsites.ge/]qartulad dublirebuli filmebi[/url]
    [url=http://allsites.ge/]geo saitebi[/url]
    [url=http://allsites.ge/]saitebi ge[/url]
    [url=http://allsites.ge/]saitebi geo[/url]
    [url=http://allsites.ge/]moda[/url]
    [url=http://allsites.ge/]saitebis katalogi[/url]
    [url=http://allsites.ge/]qartuli saitebis katalogi[/url]
    [url=http://allsites.ge/]saitebige[/url]
  21. Stanleysefsays:
    [b]Ручки РФ интернет-магазин ручек.[/b]
    [url=http://xn--h1adrmu.xn--p1ai/][img]http://fyrkunchik.ru/images/админпрез.jpg[/img][/url]


    письменные ручки
    [url=http://xn--h1adrmu.xn--p1ai/]ручка гелевая[/url]
    канцелярские товары купить
    ручка роллер паркер
    ручка роллер цена
    [b]ручка паркер роллер купить[/b]
    [url=http://xn--h1adrmu.xn--p1ai/about/contacts/]ручка синяя шариковая[/url]
  22. Stanleysefsays:
    [b]Ручки РФ интернет-магазин ручек.[/b]
    [url=http://xn--h1adrmu.xn--p1ai/][img]http://fyrkunchik.ru/images/депобраз.jpg[/img][/url]


    ручка шариковая
    [url=http://xn--h1adrmu.xn--p1ai/]подарки премиум[/url]
    поставка канцелярских товаров
    ручка роллер паркер
    ручка роллер waterman
    [b]ручка роллер faber castell[/b]
    [url=http://xn--h1adrmu.xn--p1ai/about/contacts/]ручка синяя шариковая[/url]
  23. albunnybooWsays:
    Купил както [url=http://swan-tex.eu/]текстильное оборудование[/url] могу рассказать что весь доволен приобретением, советую всем! преобритение делал через сайтa интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,приятно было.)) Вот ссылка на самолично сайт, кому нуждаться [url=http://swan-tex.eu/]все для текстеля [/url]
  24. КассовыйМастерsays:
    [url=http://www.open-sys.ru]Полный спектр услуг по продаже обслуживанию регистрациия в ифнс кассового оборудования. Кассовый центр Открытые Системы. [/url]

    При оформление заказа сейчас ! Бесплатная Доставка!!!
  25. CarrollVorsays:
    Отзывы о фронталь натяжные потолки Нижневартовск, Натяжные потолки Фронталь ханты-мансийск цена, Натяжные потолки ханты-мансийск цены, Натяжные потолки фронталь отзывы Нефтеюганск, Фронталь натяжные потолки нефтеюганск.

Comment on this Post

Remember me