Is it advisable to perform complicated calculations in an event handler? - c#

Is it considered a bad practice when someone performs complicated calculations in an event handler?
Does a calculation-cluttered .OnResize event handler has performance penalties?
If so how to make your way around them? (especially the .Print event, since thats what draws on e.Graphics)

It is not considered bad, not as such.
If your code feels cluttered, clean it up - refactor it.
Unless the event handler should be fast (say a Paint event handler), there is no problem in having it do lots of work.
If you have very intensive calculations to do and still need to have a responsive UI, you need to run the calculations on a separate thread.

I think you mean Paint event, not Print. It's not recommended when you need smooth GUI user interaction: the risk is you can steal CPU time from GUI thread and the app will appear sluggish and unresponsive. If these calculations are really a problem for user interaction, the way out is doing calculations on a separate thread, calculating results in advance and storing them in a separate buffer.

Generally, do not keep a lot of calculations inside an event handler. In event handler call, callbacks are called one by one and if one of the callbacks throws an exception then other callbacks do not receive the event. Post the calculation to a thread so that other callbacks are not affected.

Events are usually used in an event-driven system, usually one driven by the user or where a user is involved. As such, it's a good idea to keep processing short and sweet.
Sometimes, events are called in order to do some processing - apply formatting, prompt the user, provide a chance for the calling code to 'customise' what's going on. This is similar to the strategy pattern (http://en.wikipedia.org/wiki/Strategy_pattern).
To take it a step further, the strategy pattern is a good way of having a contract with the user about how they can have their say about how a process is supposed to happen. For example:
Let's say you're writing a grid control, where the user can dictate formatting for each cell. With events:
User must subscribe to the FormatCell event
With something closer to a strategy pattern:
User must create a class implementing ICellFormatter, with a FormatCell method, and pass that to the grid control - via a property, constructor parameter, etc.
You can see that the event route is 'easier' for the user. But personally I prefer the second method every time - you're creating a clear-cut class whose job it is to deal with cell formatting. It also seems more obvious to me in that case that the FormatCell method could perform some degree of processing; rather than using an Event to perform some task, which seems a bit of lazy design. (Paint is an "event"?.. not really, it's something requested of your code)

Related

How to handle an exception in an event?

So - I have this external assembly that I'm using. It fires an event DataReceived. Then I'm doing some database operations which may fail due to problems with the data or because of some errors in the code. It would be great if I could "bubble up" the exception into the GUI. In my case I would need a blocking call to the GUI because of the way the assembly works. I'm not sure if this is a good idea but right now that's the only thing that comes to mind based on how the external code works.
The assembly assumes that if the callback (the event) returned safely then the data was processed succesfully - which may not be the case. Of course I would have to deal with the error in some way but that would mean that the server on the other side would always assume that the data was handled correctly.
My questions are:
Can I throw the exception into the GUI? If so, how?
How can I handle the exception in my event so that the assembly doesn't think I processed the data? Do I need some kind of blocking call/exception into the GUI? (Is this even possible?)
On a side note: Isn't that assembly broken by design somehow? Why would it automatically assume that everything went fine just based on if the callback returned?
I don't think that this is broken by design. If you receive the event you'll get informed that something has changed in the source. Now you should only do what is needed to get the informations you need from the source and do any further processing decoupled from the source. For that purpose I would within the event handler simply grab the data (maybe from the source; maybe from the event args) and put them into a ConcurrentQueue. Within my class another Task is running that using the BlockingCollection the retrieve the elements out of this queue to process them. If anything fails, simply call Invoke() to the gui thread and inform the user about what happened.
Ah, and another approach instead of using ConcurrentQueue would be to use Rx. With that you can subscribe to an event and observe it on a different thread by using ObserveOn() which would lead to nearly the same (in this case) but using a more LINQish syntax.

Appropriate usage of C# event handlers

I'm currently building a C# application which will automatically authenticate a user against certain network resources when they connect to specific wireless networks.
At the moment, I'm using the Managed Wifi API to discover when a user connects / disconnects from a wireless network. I have an event handler, so that when any of these activities occurs, one of my methods is called to inspect the current state of the wireless connection.
To manage the state of the application, I have another class which is called the "conductor", which performs the operations required to change the state of the application. For instance, when the wireless card connects to the correct network, the conductor needs to change the system state from "Monitoring" to "Authenticating". If authentication succeeds, the conductor needs to change the state to "Connected". Disconnection results in the "Monitoring" state again, and an authentication error results in an "Error" state. These state changes (if the user requests) can result in TrayIcon notifications, so the user knows that they are being authenticated.
My current idea involves having the method used to inspect the current state of the wireless call the "authenticate" or "disconnect" methods within the state manager. However, I'm not sure if this is an appropriate use of the event handler -- should it instead be setting a flag or sending a message via some form of IPC to a separate thread which will begin the authentication / disconnection process?
In addition to the event handler being able to request connection / disconnection, a user can also perform it via the tray icon. As a result, I need to ensure these background operations are not blocking the tray's interactions with the user.
Only one component should be able to request a change of the system state at any time, so I would need to use a mutex to prevent concurrent state changes. However, how I should synchronous the rest of these components is a slight mystery to me.
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
EDIT: Most importantly, I want to verify that an event will be executed as a separate thread, so it cannot block the main UI. In addition, I want to verify that if I have an event handler subscribed to an event, it will handle events serially, not in parallel (so if the user connects and disconnects before the first connection event is processed, two state changes will not be occurring simultaneously).
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
That explains a few things. :)
I would read up on threads, event handling, and creation of system tray icons/interfaces.
It is important to note the following:
Events are processed on the same thread they are called from. If you want the processing of an event not to lock the GUI then you will need to have the button move the work to a different thread.
When an event is fired it passes the appropriate arguments to all the methods in its list. This is pretty much the same as calling one method which in turn calls all the others (see EventFired example). The purpose of events is not to call methods as we can do that already, it is to call methods which may not be known when the code is compiled (the click event on a button control would not be known when the library the control is in is compiled for example). In short, if you can call the method instead of using an event the do so.
void EventFired(int arg1, object arg2)
{
subscribedMethod1(arg1, arg2);
SubscribedMethod2(arg1, arg2);
SubscribedMethod3(arg1, arg2);
SubscribedMethod4(arg1, arg2);
SubscribedMethod5(arg1, arg2);
SubscribedMethod6(arg1, arg2);
SubscribedMethod7(arg1, arg2);
}
If you want to prevent a user interface from locking do the work on another thread. Remember though, user interface elements (forms, buttons, grids, labels, etc.) can only be accessed from their host thread. Use the control.Invoke method to call methods on their thread.
Removing an option from an interface is not a good way to prevent raceway conditions (the user starts a connect/disconnect while one is already running) as the user interface will be on a different thread and could be out of sync (it takes time for separate threads to sync up). While there are many ways to resolve this problem, the easiest for someone new to threading is to use a lock on the value. This way .NET will make sure only one thread can change the setting at a time. You will still need to update the user interface so the user knows the update is occurring.
Your general design sound fine. You could use 2-3 threads (1 for the user interface (tray icon), 1 for checking for new network connections, and 1 (could be merged with connection check) which checks the internet connection.
Hope this helps, let us know if you need more (or accept an answer).
As an option, alternative...
If I were you, and since you're starting anew anyway, I would seriously consider the
Rx Reactive Extensions
It gives a completely fresh look at events and event based programming and helps a lot exactly with the things you're dealing with (including synchronizing, dealing with threads, combining events, stopping, starting etc. etc.).
It might be a bit of a 'steep curve' to learn at start, but again, it might be worth it.
hope this helps,
To me it seems that you're going to overengineer the project.
You basically need to implement an event in Commander and in main application subscribe to them. That is.
If there is always one component can make a change and you can have more then one, using some sync mechanism, like a Mutex noted by you, is perfectly valid choice.
Hope this helps.
If you want to have at most one state change pending at any time it is probably best to have the event handlers of the external events you are listening to hold a lock during their execution. This ensure an easy way to program because you are guaranteed that the state of your app does not change underneath you. A separate thread is not needed in this particular case.
You need to make a distinction between the current state of the application and the target state. The user dictates the target state ("connected", "disconnected"). The actual state might be different. Example: the user wants to be disconnected but the actual state is authenticating. Once the authentication step is completed the state machine must examine the target state:
targetState == connected => set current state to connected
targetState == disconnected => begin to disconnect and set state to disconnecting
Separating actual and target state allows the user to change his mind any time and the state machine to steer towards the desired state.
It's hard to give a precise answer without seeing the whole (proposed) structure of your app. But in general, yes, it's OK to use an event hander for that sort of thing - though I'd probably move the actual implementation out to a separate method, so that you can more easily trigger it from other locations.
The comment about disabling the "Connect" button sounds right on to me, though it's quite conceivable you might need other forms of synchronization as well. If your app doesn't need to be multi-threaded, though, I'd steer away from introducing multiple threads just for the sake of it. If you do, look into the new Task API's that have been included as part of the Task Parallel Library. They abstract a lot of that stuff fairly well.
And the comment about not over-thinking the issue is also well-taken. If I were in your shoes, just beginning with a new language, I'd avoid trying to get the architecture just right at the start. Dive in, and develop it with the cognitive toolset you've already got. As you explore more, you'll figure out, "Oh, crap, this is a much better way to do that." And then go and do it that way. Refactoring is your friend.

How to deal with race conditions in multi-threading?

Here's an example:
if (control.InvokeRequired)
{
control.BeginInvoke(action, control);
}
else
{
action(control);
}
What if between the condition and the BeginInvoke call the control is disposed, for example?
Another example having to do with events:
var handler = MyEvent;
if (handler != null)
{
handler.BeginInvoke(null, EventArgs.Empty, null, null);
}
If MyEvent is unsubscribed between the first line and the if statement, the if statement will still be executed. However, is that proper design? What if with the unsubscription also comes the destruction of state necessary for the proper invocation of the event? Not only does this solution have more lines of code (boilerplate), but it's not as intuitive and can lead to unexpected results on the client's end.
What say you, SO?
In my opinion, if any of this is an issue, both your thread management and object lifecycle management are reckless and need to be reexamined.
In the first example, the code is not symmetric: BeginInvoke will not wait for action to complete, but the direct call will; this is probably a bug already.
If you expect yet another thread to potentially dispose the control you're working with, you've no choice but to catch the ObjectDisposedException -- and it may not be thrown until you're already inside action, and possibly not on the current thread thanks to BeginInvoke.
It is improper to assume that once you have unsubscribed from an event you will no longer receive notifications on it. It doesn't even require multiple threads for this to happen -- only multiple subscribers. If the first subscriber does something while processing a notification that causes the second subscriber to unsubscribe, the notification currently "in flight" will still go to the second subscriber. You may be able to mitigate this with a guard clause at the top of your event handler routine, but you can't stop it from happening.
There are a few techniques for resolving a race condition:
Wrap the whole thing with a mutex. Make sure that there's a lock that each thread must first acquire before it can even start running in the race. That way, as soon as you get the lock, you know that no other thread is using that resource and you can complete safely.
Find a way to detect and recover from them; This can be very tricky, but some kinds of application work well; A typical way of dealing with this is to keep a counter of the number of times a resource has changed; If you get finished with a task and find that the version number is different from when you started, read the new version and start the task over from the beginning (or just fail)
redesign the application to use only atomic actions; basically this means using operations that can be completed in one step; this often involves "compare-and-swap" operations, or fitting all of the transaction's data into a single disk block that can be written atomically.
redesign the application to use lock-free techniques; This option only makes sense when satisfying hard, real-time constrains is more important than servicing every request, because lock-free designs inherently lose data (usually of some low priority nature).
Which option is "right" depends on the application. Each option has performance trade-offs that may make the benefit of concurrency less appealing.
If this behavior is spreading multiple places in your application, it might deserve to re-design the API, which looks like:
if(!control.invokeIfRequired()){
action(action);
}
Just the same idea as standard JDK library ConcurrentHashMap.putIfAbsent(...). Of course, you need to deal with synchronization inside this new control.invokeIfRequired() method.

How to lightweight register a periodic event?

I want some code to be triggered every second. Usually, I'd create a Timer and link to its event. I wondered if there is a better way. Maybe without the requirement to implement IDisposable.
Edit: My main concern is LoC. I don't feel like writing an entire class when something along the lines of this could work, too:
System.RegisterPeriodicEvent (1000, () => { Syso("asdf"); };
In my dreams this event is automatically unregistered as soon as the current threat terminates.
I get the feeling that I should just write a class which implements the above method.
If it ain't broke, don't try to fix it.
Running x piece of code every y amount of time is what a timer does, and it does it very well.
As for avoiding IDisposable, not really, not without creating memory leaks anyway. The only two ways I can think of to do this is with kernel primitive timers (which need to be released, IDisposable), or with a thread and Thread.Sleep() or similar (and then you need to kill the thread when you're done, again IDisposable).
This isn't exactly a lightweight way of doing things, but Retlang has very nice timer functionality. In particular, it deals up front with nasty threading issues (by serializing the calls) and allows you to interleave event driven work with timers.
Best of all, you dispose of the fiber and you dispose of the event. It's not trivial though: you've got to design your code around the API (which later on you'll regard as worth it, but at first looks like a pain in the neck).

When to use custom c# events

When is it appropriate to raise an event in C#?
As an example, in our system we have data objects being sent to us, say 50 per minute, from an external system. Upon receiving a data packet, we need to have it processed by another object. Would an event or a simple method call be better to use in this situation?
An event seems like a natural fit intuitively, but I'm not clear as to what advantage this may offer as compared to simply using a regular method call.
Events should be used when it is inappropriate for the code which originates the action to have direct knowledge of the code(s) which react to that action.
On one hand, an event does sound appropriate here, because the code which handles data reception should not be dependent on the implementation of the code which does something with said data. Otherwise the data reception code is now responsible for two things - receiving the data and delegating the processing of it.
On the other hand, if the particular processing of the data is directly tied to act of it being sent by the external caller, it may make more sense to make it a function call. We don't really have enough information in your question to say for sure.
IMO using a Queue would be an appropriate first step. Code processing the Queue can in turn either raise events or accept a delegate which performs different tasks based on the kind of data object. Action or Func should work well here.
Remember that when you use events, you have to ensure that handlers get unregistered in a timely manner or else you could have leaks.
In this case an event doesn't make sense. Events tend to be to inform about what is going on, not to replace function calls. They are more informative.
So, you may want to pass in an Action<> function, so that you can then call the function that was passed in, to do the processing.
This would be better than a function call, IMO.
You can look at this page for an example:
http://www.claassen.net/geek/blog/2007/12/action-func-never-write-another.html
Update: If you are not using C#3 then you may want to use a delegate instead, which, an event handler is a specialized delegate.

Categories