Winform GUI Thread - Should there be a single catch block? - winforms

I have read it here : CodeProject
and some other places that there should be a single catch block per thread. I don't quite understand this in context of winforms. Is it true also in case of winforms? I understand that worker threads should have a single catch block. But, I have multiple catch blocks on the UI(main) thread which always end up calling my private HandleError method passing the exception. This method then takes care about how to display the errors to an user. So, say I might have a try/catch block in button1_click handler and another try/catch block in another button2_click handler. Is this a good practice? Can someone tell me if I should do something differently. Thanks.

I think you should read that rule as "there should at least be a single catch block per thread". Every thread, and certainly the main thread, should use catch blocks wherever appropriate.

I don't know of any real "rule" for using try/catch blocks. Though I'm no fan of one big try block. Use them wisely on points / lines of code where you expect possible exceptions.

Related

Handling poison messages in Apache Flink

I am trying to figure out the best practices to deal with poison messages / unhandled exceptions with Apache Flink. We have a Job doing real time event processing of location data from IoT devices. There are two potential scenarios where this can arise:
Data is bad in some way - e.g. invalid value
Data triggers a bug due to some edge case we have not anticipated.
Currently, all my data processing stops because of just one message.
I've seen two suggestions:
Catch the exceptions - this requires me wrapping every piece of logic with something to catch every runtime exception
Use side outputs as a kind of DLQ - from what I can tell this seems to be a variation on #1 where I have to catch all the exceptions and send them to the side output.
Is there really no way to do this other than wrap every piece of logic with exception handling? Is there no generic way to catch exceptions and not have processing continue?
I think the idea is not to catch all kinds of exceptions and send them elsewhere, but rather to have well-tested and functioning code and use dead letters only for invalid inputs.
So a typical pipeline would be
source => validate => ... => sink
\=> dead letter queue
As soon as your record passes your validate operator, you want all errors to bubble up, as any error in these operators may result in corrupted aggregates and data that - once written - cannot be reverted easily.
The validate step would work with any of the two approaches that you outlined. Typically, side-outputs have better semantics, but you may end up with more code.
Now you may have a service with high SLAs and actually want it to produce output even if it is corrupted just to produce data. Or you have simple transformation pipeline, where you'd miss some events but keep the majority (and downstream can deal with incomplete data). Then you are right that you need to wrap the code of all operators with try-catch. However, you'd typically still would only do it for the fragile operators and not for all of them. Trivial operators should be tested and then trusted to work. Further, you'd usually only catch specific kinds of exceptions to limit the scope to the kind of expected exceptions that can happen.
You might wonder why Flink doesn't have it incorporated as a default pattern. There are two reasons as far as I can see:
If Flink silently ignores any kind of exception and sends an extra message to a secondary sink, how can Flink ensure that the throwing operator is in a sane state afterwards? How can it avoid any kind of leaks that may happen because cleanup code is not executed?
It's more common in Java to let the developers explicitly reason about exceptions and exception handling. It's also not straight-forward to see what the requirements are: Do you want to have the input only? Do you also want to store the exception? What about the operator state that may have influenced the outcome? Should Flink still fail when too many errors have been received in a given time window? It quickly becomes a huge feature for something that should not happen at all in an ideal world where high quality data is ingested and properly processed.
So while it looks easy for your case because you exactly know which kinds of information you want to store, it's not easy to have a solution for all purposes, especially since the extra code that a user has to write is tiny compared to the generic solution.
What you could do is to extract most of the complicated logic things into a single ProcessFunction and use side-outputs as you have outlined. Since it's a central piece, you'd only need to write the side-output function once. If it's done multiple times, you could extract a helper function where you pass your actual code as a RunnableWithException lambda which hides all the side-output logic. Make sure you use plenty of finally blocks to ensure a sane state.
I'd also add quite a few IT cases and use mutation testing to harden your pipeline quicker. If you keep your test data inline, the mutants may also exactly simulate your unexpected data issues, such that your validate operator gets more complete.

Why to use multiple catch blocks?

We can use multiple catch block in Try-Catch.
But my Question is : why to use multiple catch blocks when it can be done by using single catch block?
Suppose I want exact cause of my problem, I can get that by Ex.message
If I want to show customized message to user, I can show it by putting If-Else loop on Ex.Message.
Thanks in advance.
To handle the individual exception accordingly.
For example:
If your program is handling both database and files. If an SQLException occurs, you have to handle it database manner like closing the dbConnection/reader etc., whereas if a File handling exception then you may handle it differently like file closing, fileNotFound etc.
That is the main reason in my point of view.
For point numbers 1 and 2:
If showing error message is you main idea then you can use if..else. In case if you want to handle the exception then check the above point of my answer. The reason why I stretch the word handling is because it is entirely different from showing a simple error message.
To add some quotes I prefer Best Practices for Handling Exceptions which says
A well-designed set of error handling code blocks can make a program
more robust and less prone to crashing because the application handles
such errors.
This works only if all exceptions share the same base class, then you could do it this way.
But if you do need exception type specific handling, then I would prefer multiple try-catch blocks instead of one with type-depending if-else ...
You can also ask why do we need the Switch - Case. You can do it with If - Else.
And why do you need Else at all. You can do it with If (If not the first condition, and...).
It's a matter of writing a clean and readable code.
By using single catch clock you can catch Exception type - this practice is strongly discouraged by Microsoft programming guidelines. FxCop has the rule DoNotCatchGeneralExceptionTypes which is treated as CriticalError:
Catching general exception types can hide run-time problems from the library user, and can complicate debugging.
http://code.praqma.net/docs/fxcop/Rules/Design/DoNotCatchGeneralExceptionTypes.html
The program should catch only expected exception types (one ore more), leaving unexpected types unhandled. To do this, we need possibility to have multiple catch blocks. See also:
Why does FxCop warn against catch(Exception)?
http://blogs.msdn.com/b/codeanalysis/archive/2006/06/14/631923.aspx

Winforms: Background worker - best way to KILL it

I noticed the background worker has a backgroundWorker1.CancelAsync(); method, but when you call this method, you still need to add code in the worker method, to check for a cancellation request. All this is polite and fine, but what if you just want to KILL the thread immediately? How is this done.
I want to annihilate the thread, do not pass begin and do not collect 200.
It doesn't look like a good idea...
A better programmer practice should be to check CancellationPending regularly on the thread.
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
EDIT:
Anyway the backgroundworker doesn't support it (as it's a bad programming practice), But if you really want to do that: just create yourself a normal Thread using the Thread Class

WPF Threading question better option

Here are the 2 ways we are using trying to use thread/dispatcher for multi tasking a few things:
I am wondering if anyone has any suggestions which one is better option.
Snippet 1:
Thread t = new Thread(new ThreadStart(delegate
{
MyMethod();
}));
t.IsBackground = true;
t.Start();
t.Join();
Snippet 2:
Dispatcher.CurrentDispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
(dummyDelegate)delegate
{
MyMethod();
}
);
Please advise.
Thanks
N
Neither is "better": they are different.
The first example runs MyMethod on a background thread. So if MyMethod blocks, for example on network activity or doing something computation intensive, this doesn't block the UI thread, and the UI remains responsive. (Though since your sample code blocks and waits, you are currently losing this advantage anyway.) The downside is that MyMethod has to jump through some minor hoops if it wants to read or update the UI.
The second example runs MyMethod on the UI thread. This allows MyMethod to interact without restriction with elements in the UI, but is unsuitable if MyMethod takes a long time because it freezes the UI while MyMethod is running.
So it depends on what MyMethod does. If MyMethod updates a couple of UI elements and then exits, use the second option. If MyMethod loads files or downloads data, and/or performs lengthy computation, use the first.
There is also a third option: use the Threadpool to execute a short-lived asynchronous call. For example:
System.Threading.Threadpool.QueueUserWorkItem(
delegate(object context)
{
// context is unused
MyMethod();
});
This will use a thread from the threadpool to execute MyMethod. When the method completes, the thread will be returned to the pool. The advantage of this method is that you don't have to manage the lifetime of the threads yourself, and you don't incure the memory and performance overhead of creating and destroying the thread.
Anything wrong with using good ole BackgroundWorker?
It's not WinForms specific so you can still use it in WPF.

In WinForms, why can't you update UI controls from other threads?

I'm sure there is a good (or at least decent) reason for this. What is it?
I think this is a brilliant question -
and I think there is need of a better
answer.
Surely the only reason is that there
is something in a framework somewhere
that isn't very thread-safe.
That "something" is almost every single instance member on every single control in System.Windows.Forms.
The MSDN documentation for many controls in System.Windows.Forms, if not all of them, say "Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."
This means that instance members such as TextBox.Text {get; set;} are not reentrant.
Making each of those instance members thread safe could introduce a lot of overhead that most applications do not need. Instead the designers of the .Net framework decided, and I think correctly, that the burden of synchronizing access to forms controls from multiple threads should be put on the programmer.
[Edit]
Although this question only asks "why" here is a link to an article that explains "how":
How to: Make Thread-Safe Calls to Windows Forms Controls on MSDN
http://msdn.microsoft.com/en-us/library/ms171728.aspx
Because you can easily end up with a deadlock (among other issues).
For exmaple, your secondary thread could be trying to update the UI control, but the UI control will be waiting for a resource locked by the secondary thread to be released, so both threads end up waiting for each other to finish. As others have commented this situation is not unique to UI code, but is particularly common.
In other languages such as C++ you are free to try and do this (without an exception being thrown as in WinForms), but your application may freeze and stop responding should a deadlock occur.
Incidentally, you can easily tell the UI thread that you want to update a control, just create a delegate, then call the (asynchronous) BeginInvoke method on that control passing it your delegate. E.g.
myControl.BeginInvoke(myControl.UpdateFunction);
This is the equivalent to doing a C++/MFC PostMessage from a worker thread
Although it sounds reasonable Johns answer isn't correct. In fact even when using Invoke you're still not safe not running into dead-lock situations. When dealing with events fired on a background thread using Invoke might even lead to this problem.
The real reason has more to do with race conditions and lays back in ancient Win32 times. I can't explain the details here, the keywords are message pumps, WM_PAINT events and the subtle differences between "SEND" and "POST".
Further information can be found here here and here.
Back in 1.0/1.1 no exception was thrown during debugging, what you got instead was an intermittent run-time hanging scenario. Nice! :)
Therefore with 2.0 they made this scenario throw an exception and quite rightly so.
The actual reason for this is probably (as Adam Haile states) some kind of concurrency/locky issue.
Note that the normal .NET api (such as TextBox.Text = "Hello";) wraps SEND commands (that require immediate action) which can create issues if performed on separate thread from the one that actions the update. Using Invoke/BeginInvoke uses a POST instead which queues the action.
More information on SEND and POST here.
It is so that you don't have two things trying to update the control at the same time. (This could happen if the CPU switches to the other thread in the middle of a write/read)
Same reason you need to use mutexes (or some other synchronization) when accessing shared variables between multiple threads.
Edit:
In other languages such as C++ you are
free to try and do this (without an
exception being thrown as in
WinForms), but you'll end up learning
the hard way!
Ahh yes...I switch between C/C++ and C# and therefore was a little more generic then I should've been, sorry... He is correct, you can do this in C/C++, but it will come back to bite you!
There would also be the need to implement synchronization within update functions that are sensitive to being called simultaneously. Doing this for UI elements would be costly at both application and OS levels, and completely redundant for the vast majority of code.
Some APIs provide a way to change the current thread ownership of a system so you can temporarily (or permanently) update systems from other threads without needing to resort to inter-thread communication.
Hmm I'm not pretty sure but I think that when we have a progress controls like waiting bars, progress bars we can update their values from another thread and everything works great without any glitches.

Resources