4

In my application I'm using the idle-time of the UI thread to offload expensive operations as described by MSDN article on the WPF Threading Model.

GenerateDataAction = () => { GenerateData(); };
Dispatcher.BeginInvoke(GenerateDataAction, DispatcherPriority.Render, null);

In the GenerateDate() method I access an MSSQL database, process the data in, and update bindings on the viewmodel. I have noticed since implementing this that some binding fail to update properly or not at all. I have check the output for binding errors and had a second programmer confirm the logic, also have set breakpoints within the dependency property changed method (the breakpoints do not get hit).

Is there any best-practice advice on which DispatcherPriority (link to MSDN) should be used when the invoked action contains bindings?

Dennis
  • 20,275
  • 4
  • 64
  • 80
  • That that mean that this code works consistently for some bindings? Do some bindings fail and some succeed within the same operation? If you invoke the GenerateData method directly, do all bindings work? – Phil Sandler Sep 19 '11 at 20:56
  • @Phil. When the `GenerateData` is invoked directly the bindings work as expected. – Dennis Sep 19 '11 at 21:17
  • 1
    I looked at that page, nice link BTW. Their example for BeginInvoke is very different in nature from yours. I would suggest using a Backgroundworker, Task or ThreadPool. If you only change the Source part of Databindings you should be OK. – H H Sep 19 '11 at 22:28
  • @Henk. That MSDN article is excellent - I always knew about the `Dispatcher` however not in that detail. ... The *operations* I have aren't that expensive to warrant using a `BackgroundWorker` and the single-threaded approach is ideal. – Dennis Sep 20 '11 at 07:22
  • Dennis, a Bgw uses a pool-thread, not expensive at all. I would solve the binding issue first. – H H Sep 20 '11 at 14:58
  • Apologies, the reason wanting not use a `BackgroundWorker` was not because I thought it was expensive - I know it uses a thread from the worker pool. It is more the effort of setting it up, for what really isn't a *really* expensive operation. ... HOWEVER I will try it and see if it resolves the binding issue. I suspect that the binding error is something else entirely. Thanks for the reply! – Dennis Sep 20 '11 at 15:09
  • 1
    `I'm using the idle-time of the UI thread to offload expensive operations`: you are **not** (read on). Also, `Render` priority does **not** represent the idle-time of the UI thread. `BeginInvoke` (at whatever priority) just dispatches the call/action so that it can run _in the near future_, **in the UI thread**, indeed. However, it does not somehow run the `Action` in "pieces", like whenever your UI is has "free time". Once the action is invoked, it **must run to completion**, thus blocking your UI, if expensive (see e.g. [here](https://stackoverflow.com/q/43405249/10102452)). – Vector Sigma Jul 03 '20 at 22:45

1 Answers1

3

A very good article about WPF dispatcher: http://weblogs.asp.net/pawanmishra/archive/2010/06/06/understanding-dispatcher-in-wpf.aspx

As a WPF programmer, we can push our custom time consuming logic into the queue maintained by the Dispatcher class and associate a lower priority value to that work item. Based on the value of priority field the corresponding code will be executed at the specified interval. Important thing to note here is that all the work is still being done by the UIthread, its just that with the help of DispatcherPriority we have prioritized our tasks. Ideally its recommended to give priority values less then 7(Render) to the custom logic that we wish to execute with the help of Dispatcher. Most often priority value Background is used for application specific custom logic. MS Word spell check is implemented with the help of this mechanism and priority value is ApplicationIdle.

Kelly Elton
  • 4,373
  • 10
  • 53
  • 97
WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • 1
    Thanks for the article, however it does not tell me any more information than the MSDN article on the WPF Threading Model (linked to in my question). – Dennis Sep 20 '11 at 09:05