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.
Related
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.
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.
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.
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.
I got TargetInvocationException while doing long process in another thread caused by a windows control on UI thread (Progress Bar). This exception leads my app to crash (goes to main method in debugging) and could not be caught by try catch.
I figured out what made this exception, and fix it (that was trying to assign “Value” property by a value that exceeds the maximum). But it made me wondering how I can catch exception like this (in production code) so I have an option to recover my application instead of terminating the application.
Chances are you aren't going to be able to recover very much. In terms of your operation, the state of a good number of stack frames (and objects referenced from those stack frames) is probably invalid because of the error.
Because of that, at best you can recover at a very high level and try the operation again.
If the resources you are accessing are able to be contained in a transaction, then I would suggest doing that, so that you don't have to worry about inconsistencies in persisted data.
Also, you might want to check out this thread on SO:
Best Practice for Exception Handling in a Windows Forms Application?
As well as the Exception Handling Application block from Microsoft:
http://msdn.microsoft.com/en-us/library/cc309505.aspx
You can 'handle' exceptions (really, you're just receiving notification of them) on the GUI thread via the static event Application.UnhandledException.
When you attach a handler to this event, it will be invoked for all unhandled exceptions on the WinForms UI (message pump) thread. The fact that you have this handler attached means that the Application won't exit. Without it, WinForms shuts down your application.
Catch the exception and find a mechanism to pass it back to the main or calling code.
Not sure what version of .net you are using if its 3.0+ you can do something along these lines.
private void UpdateValue(int newValue)
{
Action myAction = () => progressBar.Value = newValue;
if (progressBar.InvokeRequired)
progressBar.Invoke(myAction);
else
myAction();
}
Call this method with the new value for the progress bar it will check if the call needs marshalling and make the appropriate call. Be careful InvokeRequired is relatively expensive, so use it only where needed. You could make this into an extension method to make generic use of this pattern for other controls if needed.
Hope this helps.