views:

1090

answers:

6

I tried to wrap the dispatcher in a thread. But the result is not what i expect. How can i solve that problem?

    public void Start()
    {
        ThreadStart ts = inner;
        Thread wrapper = new Thread(ts);
        wrapper.Start();
    }

    private void inner()
    {
        _Runner.Dispatcher.Invoke(_Runner.Action, DispatcherPriority.Normal);
    }
+4  A: 

You have not shown us enough code/explained yourself well enough to be able to provide a good answer, but I'm guessing your action (_Runner.Action) is expensive and slow to execute. If so, that is why your UI is unresponsive. You're essentially telling the Dispatcher to run that expensive operation on the UI thread when what you really want to do is run as much of your operation on the background thread as possible, and then marshal back to the UI thread via the Dispatcher only when necessary.

HTH, Kent

Kent Boogaart
My thoughts exactly.
Josh G
The background thread does not help if it immediately calls the dispatcher to execute the task on the UI thread.
Josh G
+1  A: 

When you fire an action through/on the dispatcher, that action is called on the UI thread.

My guess is that you are doing the work/processing in the _Runner.Action function and it is tying up the UI thread. You'll have to do the main processing part in the inner() function and then call the Dispatcher for the final update details.

If you absolutely must process on the dispatcher, break your process into smaller pieces and call Dispatcher.BeginInvoke() for each piece so other events can be processed in between your process.

Josh G
A: 

Yes. _Runner.Action is the problem. Some long-timed methods used in the Dispatcher block. But solution is "dont use the any thread not related to UI in the dispatcher"

+1  A: 

Here is an example that will let you run WPF applications with multiple UI threads. I believe this will help you. Refer to this http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/

Thread lThread = new Thread(() =>
                   {
                        var lWnd = new Window1();
                        lWnd.Show();
                        lWnd.Closed += (sender2, e2) => lWnd.Dispatcher.InvokeShutdown();
                        System.Windows.Threading.Dispatcher.Run();
                   });
lThread.SetApartmentState(ApartmentState.STA);
lThread.Start();
Vasu Balakrishnan
+1  A: 

You need to break Runner.Action into two parts - the long running part that does the calculation and the part that updates the GUI.

After you do that you call the long running part in the background thread and use the dispatcher only on the UI update part.

By the way, you should also probably use BeginInvoke and not Invoke.

If the long running part of Runner.Action is updating the GUI than you can't use a background thread to solve your problem - there are solutions for slow GUI operations but they change depending on what exactly you are trying to do.

Nir
+1  A: 

Ditto what everyone here has said.

Additionally, you may want to look into using the BackgroundWorker class.

Ray