4

I am working on a project of my company in which they used Dispatcher.Invoke() in many places.If I am using BeginInvoke instead of Invoke then the Synchronisation between threads working fine but in case of Invoke the application is freezing and even not entering the execution to the delegate method also. Does anybody have any idea why it is happening like this?

Any answer will be appreciated.

Sample Code for Invoke used in the Project:

Dispatcher.Invoke(DispatcherPriority.Send,
                  new DelegateMethod(MethodtoExecute));

private delegate void DelegateMethod();

 void MethodtoExecute()
        {
            try
            {

            }
            catch (Exception /*ex*/)
            {

            }
            finally
            {

            }
        }
svick
  • 236,525
  • 50
  • 385
  • 514
SharpUrBrain
  • 3,180
  • 5
  • 38
  • 56
  • 1
    Have you tried this solution: http://stackoverflow.com/questions/264163/wpf-dispatcher-invoke-hanging – mikus Sep 29 '11 at 09:20
  • No, i did not try this solution let me look into it, any way thanks for the link :) – SharpUrBrain Sep 29 '11 at 09:22
  • We need more information: How are you getting the `Dispatcher`? On what code is the main thread when it's freezing? – svick Sep 29 '11 at 11:55
  • @Hans Passant: But in certain circumstances I do not allow user to access the UI, So for that I need to block the UI until and unless I finish the job in background. – SharpUrBrain Sep 29 '11 at 15:40
  • @all: But if there is multiple Dispatcher.Invoke/BeginInvoke is used in the whole application then will all run in Main thread ? – SharpUrBrain Sep 29 '11 at 15:43
  • 1
    No, you prevent access with the IsEnabled property. Blocking the ui thread only produces deadlock. – Hans Passant Sep 29 '11 at 15:49
  • @Hans Passant: You mean IsEnabled property of the UI control ? – SharpUrBrain Sep 29 '11 at 15:51

1 Answers1

4

Dispatcher.Invoke executes synchronously on the same thread as your application, so whatever you invoke is able to block the main application thread. Dispatcher.BeginInvoke executes asynchronously, so it doesn't tie up the main application thread while executing.

Since you are using DispatcherPriority.Send, which is the highest dispatcher priority level, whatever you are invoking gets run before anything else, including rendering the screen or listening for events. I'd recommend switching that to DispatcherPriority.Background, which runs at a lower priority than Render and Input. See this page for a list of the DispatcherPriority levels and their execution order

I'd highly recommend you look at the answer posted here

Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • 2
    The delegate that is passed to `Dispatcher.Invoke` or `Dispatcher.BeginInvoke` executes on the main thread. The difference is that `BeginInvoke` doesn't block *the thread that calls it*. – svick Sep 29 '11 at 14:51
  • @svick Both Dispatcher.Invoke and Dispatcher.BeginInvoke executes on the main thread? How BeginInvoke does not block the thread? – Syed Sep 29 '11 at 19:08
  • 2
    @Syed, all `BeginInvoke` does is that it schedules the code for execution on the main thread and then immediately returns. So it does not block the thread that calls it. But if there is some long computation or anything that blocks in the delegate, then it blocks the main thread. – svick Sep 29 '11 at 19:13
  • @svick Nice explanation, BeginInvoke does not run on the secondary or worker thread? – Syed Sep 29 '11 at 19:16
  • @Syed I posted a link in my answer to another good SO answer. I'd recommend taking a look – Rachel Sep 29 '11 at 19:34
  • @Syed, that's the whole point of `Dispatcher`: to run some code on the main thread. – svick Sep 29 '11 at 21:50
  • @Rachel, the link you posted is about `Control.(Begin)Invoke`, but the situation with `Dispatcher` is very similar. – svick Sep 29 '11 at 21:52