ThreadOption.UserInterface not working for me

Topics: CAB & Smart Client Software Factory
Feb 4, 2006 at 7:09 AM
originally posted by: Cubes

I'm sure I've got something messed up here or don't understand how this should work.

I have a background thread created using a ThreadStart delegate. It listens in the background for removable media (usb key) to be inserted into the computer. It fires an event that is published using the event broker:

EventPublication("topic://MediaInserted", PublicationScope.Global)

Then a subscriber is supposed to run a workitem which swaps out the main workspace.

EventSubscription("topic://MediaInserted", Thread = ThreadOption.UserInterface)
public void OnMediaInserted(object sender, EventArgs args)
{
DesktopWorkItem desktopWorkItem = this.WorkItems.AddNew<DesktopWorkItem>();
desktopWorkItem.Run();
}

Here is the workitem:

public class DesktopWorkItem : WorkItem
{
protected override void OnRunStarted()
{
base.OnRunStarted();

DesktopViewer viewer = this.Items.AddNew<DesktopViewer>();
this.Workspaces"MainWorkspace".Show(viewer);
}
}

It creates a smart part and shows it in the "MainWorkspace".

I get the following exception (Subscription.cs) in the CallOnUserInterface method:

InnerException = Cross-thread operation not valid: Control 'MainWorkspace' accessed from a thread other than the thread it was created on.

It seems like it's not running the DesktopWorkItem on the UserInterface thread...
Feb 7, 2006 at 3:22 PM
originally posted by: BradWilsonMSFT

I've used the UI thread functionality of EventBroker without problem. Can you reproduce this with a very simple sample?
Aug 19, 2006 at 3:35 AM
originally posted by: RohanSuperS

I have the same problem. Does anyone know what the solution is?
Aug 19, 2006 at 8:27 AM
originally posted by: mamu300B

RohanSuperS,

What actual problem do you have?
What work item hierarchy? What items are involved and how are they created/instanciated?
Please elaborate your findings in more words than simply saying "it doesn't work for me either!").
Or otherwise i could simply agree to Brad and say that it does work in my multithread situations?
Aug 22, 2006 at 5:11 AM
originally posted by: Glorat

Just to throw in what little I have experienced myself.

I have an EventPublisher that publishes on a background thread.

I have two EventSubscribers both listning on ThreadOption.UserInterface, one on a random WorkItem and one placed on the ShellForm. The event on the shell form is raised on the UI thread but the one on the WorkItem is not.

If this isn't to be expected, would a small demo app help or have people been able to reproduce this?
Aug 22, 2006 at 8:43 AM
originally posted by: mamu300B

Hello Glorat,

what do you mean by

>>The event on the shell form is raised on the UI thread but the one on the WorkItem is not.

Did you mean the method that is tagged using EventSubscriptionAttribute gets called when the event is fired from within the worker delegate?

The only thing that is guranteed is that all public methods that have the event handler's signature and are marked with the EventSubscriptionAttribute will get called.
And on the subscripers side you specify whether you need to do UI handling things. If you do UI, you have to request a thread context switch by specifying "Thread=ThreadOption.UserInterface".
And only in this situation a context switch is done!

Do you have any problems with your code?
Aug 22, 2006 at 10:35 PM
originally posted by: Glorat

I should clarify my sentence!

The eventsubscribption on the shell form is called on the UI thread but the eventsubscription on the WorkItem is called on a non-UI thread, as confirmed by checking View.InvokeRequired. This is despite both eventsubscriptions being marked as ThreadOption.UserInterface

Kevin
Aug 24, 2006 at 8:26 AM
originally posted by: mamu300B

Kevin,

I'm not able to reproduce the problem.
What confuses me: what do you mean by "View.InvokeRequired"?
A WorkItem has no View property. And the event subscriper that creates the other DesptopWorkItem is in a workitem, isn't it.

If you like to, send be your code to "b o s s . m u e l l e r at w e b . d e" (remove all whitespaces and replace "at" with @).
In my test scenario I have:
- a class with a method that starts a worker thread and that publishes an event.
- within the worker delegate i fire the event.
- the subscriped view, controller, and workitem all get triggered.
- within the event handling method of the workitem i create a new workitem and run it.
And everything is fine!

-Matthias
Aug 25, 2006 at 9:41 AM
originally posted by: mamu300B

after getting some sample code from Kevin it turned out that everything works as expected (to me :-; ).
If you want the EventBroker (Subscription.cs) do the thread context switch to UserInterface, you have to ensure that there is a System.Threading.SynchronizationContext set.
Windows.Froms and Controls do this for you but a WorkItem does not.
If you want to have a WorkItem to have a SynchronizationContext call "SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext())" in its constructor or its InjectionConstructor.

Hope that help anyone
-Matthias