If I'm firing the event:
var handler = OnMyEvent;
if (handler != null)
{
handler(some_info);
}
then will the execution thread wait until all suscriber methods return to continue the execution after line:
handler(some_info);
?
Or events are fired "in another thread", meaning that it automatically goes to the next line after handler(some_info)?
Events are fired on the same thread and it will block until they are completed. Of course the event handling code itself can spawn another thread and return immediately but this is completely different matter.
Also note that events like button clicks in a desktop applications like Windows Forms apps are put on a message queue and will fire one at a time. i.e. if you press a button and then press another button the second button event will not fire until the first is completed. Also the form will not repaint and will be "not responding" because painting the form is also an event.
Events are fired in the thread that raised them.
Related
Does the blocking of a thread also blocks the firing and/or propagation of event fired from it?
To clarify:
On a thread I am firing an event and as a next step I let the thread fall asleep. The question is whether the firing - if stated immediately before the statement to go sleep - is also blocked to fire due to a scheduling issue (i.e. the event has been scheduled to fire but actual firing will take place in say 100 ms and before these 100 ms have been passed the thread has been fall asleep).
// Pseudo-Code
event MyHandler TheEvent;
// ...
TheEvent();
threadWaitingSignal.Wait(); // block the thread
What assumptions can I make in the above scenario regarding the firing and the delivery of the event to its subscribers ?
All listeners will receive the event before the thread sleeps. Events are fired synchronously.
I have developed a C# application which makes heavy use of events. Now this application is occasionally doing funny things that I cannot understand or track down to a specific cause why they should occur. I reckon that the cause for these intermittent malfunctions is some sort of concurrency or race condition which I did not anticipate.
How exactly are events handled in C#? If an event is raised, will (a) the portion of code attached to that event be executed immediately? Or will the event (b) be put on a stack of events and be executed whenever .NET deems it suitable for execution while other code is executed in the meantime?
If an event is raised, will the portion of code attached to that event be executed immediately?
Well, yes and no. Events are multicast delegates, so there might be zero, one or many "portions of code" attached to an event. In the scenario where there are many, clearly one of them has to go first and one of them has to go second. The one that goes second isn't executed immediately upon the event being raised; it's executed immediately upon the first event handler completing normally.
will the event be put on a stack of events and be executed whenever .NET deems it suitable for execution while other code is executed in the meantime?
Suppose your application is badly written and hangs the UI. While the UI is hung, the user clicks on button 1 and button 2. Since the application is hung, nothing visible happens. The events for button 1 and button 2 being clicked do not fire. But Windows has created a message queue and enqueued on it the fact that button 1 and button 2 have pending clicks that need to be processed when the application unhangs itself. When the message loop is pumped then the button 1 click event fires. When it is done doing its thing, the message loop is pumped again and the button 2 click event fires.
So yes, in that sense events are queued up and executed later, but it is not "when .NET deems it suitable"; it's when the thread that is processing the message queue starts processing the message queue again. There's no mysterious Windows policy in here controlling your code.
It entirely depends on the event raising (and subscription) code.
If you're raising the event like this:
EventHandler handler = MyEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
or something similar, then all the event handlers will be executed immediately. That's the typical implementation... you have to work a bit harder to put each event delegate into WinForms message queue or something like that.
If you could give us more information about what events you're talking about and how they're implemented, we may be able to help you more.
For more information on events and delegates (and the difference between them) you may wish to read my article on the topic.
C# events, just like the rest of delegates, are executed immediately when triggered.
Unless explicitly implemented otherwise, events are called synchronously.
Typically the code that triggers an event looks like that:
public event EventHandler MyEvent;
protected virtual void OnMyEvent()
{
EventHandler handler = MyEvent; // keep a copy to avoid race conditions
if (handler != null)
handler(this, EventArgs.Empty);
}
As you can see from this code, event handlers are called immediately and synchronously from the OnMyEvent method.
I believe your question has been answered here:
Are Event Handlers processed Asynchronously?
In short, it depends on your implementation, but the default event handling is processed synchronously. There are, however, ways to make it asynchronous.
As stated in the previous awnser, it entirely depends on the code that is raising the event or handeling the event.
What above examples are missing is properly code on how to raise/handle events. I'm aware that they're just quick examples, but nonetheless, good practise is important.
If you want good examples/material on how events can be properly processed in C#, you could take a look at this article: http://www.codeproject.com/KB/cs/event_fundamentals.aspx
My dotnet application handles the following SystemEvents.
Systems.SessionSwitchEvents
Reason : Lock and Unlock
Systems.OnPowerModeChanged
Modes : Resume and Suspend
Network events
Now the Resume event triggers 3 events
unlock , resume and some network events ( some times it triggers multiple network events (up/down ) not stabilized)
Now i have a functionality which is all the same for all these events which i have implemented in thier corresponding event handlers.
I want a sync when a resume event occurs.
basically want to signal the resume event handler when both unlock and network Up events have occured until then the Resume event handler should sleep.
IS there a way to signal my resume event handler when two events occur.
Thanks
It sounds like you need to count your events and block until they have all been triggered. A Countdown type would be appropriate. See this example Countdown event.
I have a button in my program that supposed to be clicked after a while loop finished, whats the code to click the button?
To programatically click a button just call the Click method:
button.Click();
Note that this doesn't cause the UI to update as if the button had been pressed - it just results in the event handler for the click event being run.
In your question you mention that you are running a while loop that presumably takes some time. If you do this in the naive way - running it in the main application thread - it will cause the UI to block while the loop is running. To fix this you need to run the while loop in another thread, for example by using a BackgroundWorker. But then when your loop finishes you have to be careful to ensure that the click event is called back on the main thread. The general way to do this is to use Invoke, but in the specific case that you have a BackgroundWorker you can run the code after the loop finishes in the OnRunWorkerCompleted event handler then you don't need to call Invoke yourself as the BackgroundWorker takes care of this for you.
I'm writing a little chat app, and I have this event handler:
void o_Typing(object sender, EventArgs e)
{
MessageBox.Show("Fired!");
this.Text = "Fired!";
}
o_Typing is a method in a class derived from TabPage. Basically, I want each conversation to have it's own tab.
The event handlers are fired by my Chat object, which is running in another thread. I have 1 thread for UI, and another thread for each Chat conversation (to keep polling the server for new data)
When the event is fired, the MessageBox pops up, but the Tab caption doesn't change. After the event has fired once, it never fires again, leading me to believe that the event is being called in the worker thread, although it is defined in the UI thread.
How can I get my events to be called from the worker thread, and use Invoke() to get them to execute on the UI thread?
There are two options:
1) Make the event handlers thread-safe: use Control.Invoke/BeginInvoke in any event handler which needs to talk to the UI thread.
2) Make the worker thread marshal back to the UI thread before raising the event - in other words, use Control.Invoke as part of the process of raising the event, so that the event handlers will all be called in the UI thread. Depending on how your app is structured, you may not want your event-raising component to know about the UI explicitly - but when it's being constructed you can pass in an ISynchronizeInvoke (which Control implements) and your component can use that to raise its events on the right thread. Of course, that only works (simply, anyway) if every event handler is happy to run on the same thread - but that will often be the case. You'd write something like:
protected void OnFoo(EventArgs args)
{
if (sync != null && sync.InvokeRequired)
{
sync.Invoke((Action) delegate { OnFoo(args) }, null);
return;
}
EventHandler handler = Foo; // Where Foo is the event name
if (handler != null)
{
handler (this, args);
}
}
If you fire your event in code which is executed by your worker thread, then all methods subscribed to the event will be executed under that worker thread.
For GUI-elements you need to look at the Invoke-methods.
Best Regards