views:

49

answers:

1

Say I have two usercontrols, UC1 and UC2. A user selects something in UC1, which takes some time so the process is threaded off. UC2 needs to update its view and do some work of its own on another thread when UC1 finishes. But UC2 is dependent on the output of the UC1 background thread so it has to wait until that thread is finished before it begins.

UC1 needs to update an ObservableCollection to update its view when its background thread finishes, as does UC1, asynchronously.

Whats the best way to do this? I have tried just threading them off and firing a message from UC1's thread, but then UC2 cant modify its ObservableCollection because it is not on the right thread- it thinks its on UC1's thread.

Do I need to marshall the message event from UC1 to UC2, is this safe?

How do people normally handle this?

+1  A: 

Both UserControls should live on the same thread. This is how WPF is designed.

Since UC2 depends on an event that UC1 also depends on, I would have UC1 scope the lifetime of the event, and send the message to UC2 when the work is done, or else have UC2 subscribe to the ObservableCollection's CollectionChanged event. They both live on the same UI thread, so marshalling between them is not needed, you just need to marshal the background thread to the respective UserControl.

codekaizen
No, while true that both UC1 and UC2 are on the same UI thread, if in UC1 you start a new background process thread to do work- its a new thread that neither UC1 and UC2 are on. If you fire a message from this thread that UC2 picks up, the message event is still on that background thread so you cannot do anything with your observablecollections. This is where I was thinking you would have to marshall that background thread back to the UI thread and then let UC2 do its work.
Nicros
Oops sorry, missed that last sentence- I guess the question would be how do I marshall the message from my BackgroundWorker thread on to the UI thread of the user control that recieved the message?
Nicros
Mission complete!Using BackgroundWorker is the key, as any RunWorkerCompleted event handlers are automatically back on the UI thread (in my case). Cool.
Nicros
@Nicros - Glad you found the right path. BackgroundWorker is a great component, made just for this. However, you don't absolutely need it, and you could have performed the marshalling from the worker thread yourself, by using the UC Dispatcher to send the event from the background thread to the UI thread. This is essentially what BackgroundWorker does.
codekaizen