I am writing a C# program, which uses the UI Automation via Com interop. However, I am having a problem adding/removing an event handler from within another event handler:
My program starts up a new MTA thread, and on that thread, calls AddFocusChangedEventHandler().
I want to monitor for property changes on the focused element. So within the focus-changed handler, I call RemovePropertyChangedEventHandler() on the previously focused element, and AddPropertyChangedEventHandler() on the newly focused element.
However, I find that after about two focus changes, I stop getting either focus-changed, or property-changed, events. My hunch is that something is blocking the background thread.
If I remove the property-changed code, then just the focus tracking works just as expected.
I'm not sure if this is pertenant - but the documentation states that event handlers should be added/removed on the same thread. Since I'm calling AddPropertyChangedEventHandler() in one focus-changed event, and RemovePropertyChangedEventHandler() in another focus-changed event, it's possible that the two calls are being executed on different threads. However, I doubt this to be the case - and even if it were, it shouldn't exhibit the blocking behavior I see. Just mentioning it here for completeness.
There may be multiple problems here. But it's worth noting that after you RemovePropertyChangedEventHandler, you may still get some more events if there are multiple events on the same item (you'll for example get multiple child_added structure changed events if there are multiple children added to an item, it may be similar with multiple properties changing - but not sure). So, if you get multiple events, your code will be called multiple times, probably messing things up.
Another issue is, as you've pointed, you shouldn't subscribe / unsubscribe to events from different threads. But I think this is relevant when there's a chance that these actions are not synchronized - if you're subscribing and unsubscribing to different events (likely in your case) then things will get messy - I'll hazard to say that if you do the subs/unsubs in sequence by some lock mechanism then it should be fine.
Related
There is an issue that makes me curious about for quite some time.
Assume this scenario:
You created a program in C#, which has some classes inwhich you defined some events,
and other classes consume those events - they implement event handler methods for them.
My question:
What are the CLR's "rules" for running the event handler(s), for cases where events happen simultaneously?
If one event handler is running, and another event was raised now, will the CLR let the current event handler finish, and then just go to the next event handler? (the "second" event might be a second raise of the same event, or a different event)
Or is there a case where the CLR pauses the current event handler due to an event that came in the middle, then runs the second event handler, and then resumes back to the middle of the first event handler that was left?
Any info or article that makes an order in this, will be greatly appreciated.
BTW:
For this question, please assume 2 possible situations:
1) The classes with the events and event handlers are not Controls
(simple classes that you write, that inherit type object and not type Control)
2) The classes with the events and event handlers are inheriting class Control (Windows Forms)
I mention this because maybe the behavior/rules are different between the two.
Also, I would be grateful if you can relate to following things, that might affect the answers to these 2 questions:
- Application.DoEvents() method
- Timers
- any other class/method like this that might give different results beyond the simple ones that we might think of in the "normal" case..
Thank you
This has nothing to do with the CLR or the language. It's purely based on the specific implementation of the class defining the method. It can be written such that it fires of the event while handlers for a previous invocation are still running, or it could not. If you're dealing with a winforms program then most object firing events are firing them in the UI thread, so since there is only one thread that can be firing the events it can't ever fire them while other handlers are still running, but there are other objects that aren't forcing their usage to a single thread and as such can fire an event while handlers for a previous invocation are still running.
So all you can really do is look at the documentation/source code or do some experimental tests to see what any particular class does, or be safe and assume the worst case. There is no general case answer.
The scenario is an event on a buffer, that informs interested classes when there is data available to be collected. The event is fired as soon as new data is written to the buffer. When this is fired, the delegate for the event (in the interested class) starts reading data from the buffer.
My question is, if the event were fired again (before the method had finished reading all the data from the buffer) would the reading method be 'reset' or would the event wait for the method to finish reading the data before calling it again?
The event could only be fired again before the method had finished reading if it were fired on another thread. The event handlers will then (by default) be called again in that separate thread. There's no concept of an existing method being "reset", nor would it wait for the already-running handlers to finish before firing again.
Of course, you could potentially change how the handlers work, or how the event is fired - perhaps ensuring that the event handlers are only called from a single thread, with some sort of queue of events. It's impossible for us to tell whether that's appropriate for your situation though.
Neither, it would execute it alongside (in parallel), if on separate threads - otherwise execution would be blocking anyway.
Unless you've put Application.DoEvents() in your code (which is a horrible thing to do) then your event won't be interrupted.
In a multithreading scenario, there's the possibility of them running in parallel. I don't use multiple threads and events both at the same time, so I can't really say much about that, but it seems like Jon's covered that one nicely with his answer.
I am having a lot of trouble with AppDomains. I currently have an AppDomain containing camera controls, and am trying to have events raised from this secondary AppDomain (like a picture being taken) come back to the main program. Everything seems to be set up correctly (events are registered, functions will run across domain boundry) but when I try to invoke, nothing happens. Everything I can find on the subject involves exceptions being raised rather than just nothing happening at all.
I don't know how much better I can explain it than this, so I made a (very simplistic) diagram, and can post any code that is necessary.
http://a.imageshack.us/img832/8205/cameradiagram.png
A breakpoint fires in the OnPictureUpdated.Invoke(pic); portion, inside the secondary AppDomain, but nothing (either inside CameraContainer or in the main application is raised. I am doing a null check when invoking events, I just didn't put that in the diagram.
+1 for the effort in the question.
I believe this may just be because your CameraContainer isn't a MarshalByRefObject. Because it's attaching to the event, the AppDomain containing the CameraManager effectively needs to call back into the primary AppDomain when the event is raised.
I have a number of Windows Forms controls which are used to interact with my program objects. Currently they subscribe to an "Updated" event on the object and manually update values when needed. I would like to replace all (or as much as possible) of this boilerplate code using data binding.
The problem I'm running into is that the object state can be modified by any one of several different threads at any moment. Currently I use Invoke() to handle this, which works fine, but when I switch to data binding I get swamped by illegal cross-thread control exceptions. Is there a preferred method to handle this gracefully using data binding, or am I better off just leaving things the way they are now?
Thanks!
If you are data binding your controls to the data sources that are being updated from the underlying thread, then you will have to move the code that does the updating to the UI thread through a call to Invoke.
Or, if you want, you could get a ISynchronizeInvoke implementation (or a SynchronizationContext) and have all the events fire on the UI thread. Of course, this could cause unintended problems with your code, as you weren't firing the events on the UI thread in the first place.
I'm having a problem with handling an event on a different thread from where it is raised. The object that is handling the event is not an UI object however, so I can't use Invoke to execute the delegate and automatically switch to the UI thread for event handling.
The situation is as following: I have an MDI application containing multiple forms. Each form has it's own controller class that handles communication between the coupled form and external objects. All forms are either overview or detail forms (e.g. ContactsOverview & ContactDetail) and share the same data.
In the situation where the error occurs the forms appear in a wizard-like sequence, say a detail form is followed by an overview form. In the detail form data used on the following overview form is changed and before switching to the overview form these changes need to be reflected there. An event is raised from the detail form and handled by the controller for the overview form which does the necessary updating of UI elements.
Now the saving of the changed data in the detail form can take a while so it is necessary that the UI remains responsive and other parts of the application can still be used. This is why a backgroundworker is started to handle this. When the data is saved the event is raised on the background thread. The controller for the overview handles this but when the UI needs to be update there are of course cross-thread exceptions.
So what I need is a way to raise the event on the UI thread, but since the handling doesn't happen on a UI element there's no way to switch threads automatically using Invoke.
From searching around the web I've found one possible solution which is using the producer/consumer pattern. But this would require each controller to listen to a queue of events in a separate thread as far as I understand. Since it's an MDI application there could theoretically be any number of forms with controllers and I don't want to be starting up that many threads.
Any suggestions are welcome. If there would be a way to avoid using the backgroundworker alltogether that would be a suitable solution as well.
Thanks for reading,
Kevin
You can use SynchronizationContext, specifically SynchronizationContext.Current, to post messages to the main synchronization context (which is the main thread for a GUI application).
Unfortunately I don't know enough about the class and its usage to say this is a definite solution. In particular, I don't know what you should do if you don't require the main thread to handle your events, but instead a particular thread.
Perhaps the WindowsFormsSynchronizationContext class can help you out, it has a public parameterless constructor, I'm thinking it might associate it with the current thread, so if you construct that object from the thread that owns the controller, and give it to the background thread code, it might work.
You can have an event on the background objec that the UI element subscribes to. In the event handler (of the subscription - so it is part of the window code) you can then to the invocation. This is how I solve this.
You can try this flag but I don't think it's the best idea, just a work around.
You could also try to instantiate the issuing objects in a non-graphical thread, which may fix your problem.
One more thing, can't you have your UI component handle RunWorkerCompleted (with indirections) ?