C# - Exception Propagation Issue in AsyncCallback - c#

The following code is pretty self-explanatory and my question is very simple :
Why is AsyncCallback method "HandleConnect" not propagating exception to the "Connect" method and how to propagate it ?
public void Connect(IPEndPoint endpoint, IVfxIpcSession session)
{
try
{
ipcState.IpcSocket.BeginConnect(ipcState.IpcEndpoint, HandleConnect, ipcState);
}
catch(Exception x)
{
ManageException(x.ToString()); //Never Caught, though "HandleConnect" blows a SocketException
}
}
private void HandleConnect(IAsyncResult ar)
{
// SocketException blows here, no propagation to method above is made.
// Initially there was a try/catch block that hided it and this is NOT GOOD AT ALL
// as I NEED TO KNOW when something goes wrong here.
ipcState.IpcSocket.EndConnect(ar);
}
1 - I guess this is pretty normal behavior. But I would appreciate a comprehensive explanation of why is this happening this way and what happens exactly behind the hoods.
2 - Is there any (quick and simple) way to propagate the exception through my app ?
forewarning I know many dudes in here are very critical and I anticipate the comment "Why don't you put the ManageException directly in the "HandleConnect" Method. Well, to make a long story short, let's just say "I got my reasons" lol. I just posted a code sample here and I want to propagate this exception way further than that and do much more stuff than showed in other places in the "N-upper" code.
EDIT
As an aswer to a comment, I also tried this previously indeed, with no luck :
private void HandleConnect(IAsyncResult ar)
{
try
{
ipcState.IpcSocket.EndConnect(ar);
}
catch(Exception x)
{
throw x; // Exception Blows here. It is NOT propagated.
}
}
My Solution :
I ended up putting an Event Handler to whom every concerned code logic subscribes.
This way the exception is not just swallowed down nor just blows, but a notification is broadcasted.
public event EventHandler<MyEventArgs> EventDispatch;
private void HandleConnect(IAsyncResult ar)
{
try
{
ipcState.IpcSocket.EndConnect(ar);
}
catch(Exception x)
{
if (EventDispatch!= null)
{
EventDispatch(this, args);
}
}
}
//Priorly, I push subscriptions like that :
tcpConnector.EventDispatch += tcpConnector_EventDispatch;
public void tcpConnector_EventDispatch(object sender, VfxTcpConnectorEventArgs args)
{
//Notify third parties, manage exception, etc.
}
This is a little bit crooked, but it works fine

When you use BeginConnect the connection is done asynchronously. You get the following chain of events:
Connect "posts" a request to connect through BeginConnect.
Connect method returns.
The connection is done in the background.
HandleConnect is called by the framework with the result of the connect.
When you reach step number 4, Connect has already returned so that try-catch block isn't active any more. This is the behavior you get when using asynchronous implementations.
The only reason you would have an exception caught in Connect is if BeginConnect fails to initiate the background connection task. This could e.g. be if BeginConnect validates the supplied arguments before initiating the background operation and throws an exception if they are not correct.
You can use the AppDomain.UnhandledException event to catch any unhandled exceptions in a central place. Once the exception reaches that level any form of recovery is probably hard to achieve, since the exception could be from anywhere. If you have a recovery method - catch the exception as close to the origin as possible. If you only log/inform the user - catching centrally in once place is often better.

One option is to use AsyncWaitHandle with your existing code.
For better exception handling, you would have to either use event based programming model or modify your code to use BackgroundWorker component which supports reporting error from the worker thread to the main thread.
There are some discussions and articles present on this topic at following links:
http://openmymind.net/2011/7/14/Error-Handling-In-Asynchronous-Code-With-Callbacks/
MSDN Sample: http://msdn.microsoft.com/en-us/library/ms228978.aspx

Further to what Anders has pointed out, it is probably a good idea to read this:
http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx
and look into how you can pass a callback method into the asynchronous call to BeginConnect (if one does exist) using something like an AsyncCallback where you can retrieve the delegate and call EndInvoke within a try catch block.
E.g.:
public void
CallbackMethod
(IAsyncResult AR)
{
// Retrieve the delegate
MyDelegate ThisDelegate =
(MyDelegate)AR.AsyncState;
try
{
Int32 Ret = ThisDelegate.EndInvoke(AR);
} // End try
catch (Exception Ex)
{
ReportException(Ex);
} // End try/catch
} // End CallbackMethod

Related

Is it possible to not break execution flow on certain exceptions but break on others - and if so, how?

I need to call several methods from an external framework - or rather I am writing a wrapper around it for other users to call methods from this framework in a non-predetermined order. Now some methods of the framework will throw exceptions, even though no "real" error occured. Basically they are supposed to be internal exceptions just to notify whoever that the action to be performed has already been performed before. For example: that a file has been loaded. It wont hurt to load the file another time, so for all I care this "error" is no error at all. So I need to continue on this exception, but I also need to catch other, real exceptions, such as when the framework, which connects to clients and stuff, cannot do so.
Below I have some (extremely simplified) example code. Obviously that code wont compile because the code for the custom exceptions is missing. Also in real life the code is spread over three assemblies. This means, that I cannot wrap the exception handler around those framework methods which will throw InternalFrameworkException() only. I can only wrap it around the whole SomeMethod(). As I wrote, this is an extremely simplified example.
Is there any way to handle the RealException()s but continue the InternalFrameworkException()s without using PostSharp as mentioned here? Note that this is not about letting the InternalFrameworkException() fall through, but they should actually not break out of the try{} block at all.
namespace ExceptionTest
{
using System;
internal class Program
{
private static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (InternalFrameworkException exception)
{
// Do not actually catch it - but also dont break the
// execution of "SomeMethod()".
// Actually I never want to end up here...
}
catch (RealException exception)
{
// Break the execution of SomeMethod() as usual.
throw;
}
catch (Exception exception)
{
// Again, break the execution of SomeMethod() as usual.
throw;
}
finally
{
// Clean up.
}
}
#region == Method is actually contained in another assembly referencing this assembly ===
private static void SomeMethod()
{
// Should break if uncommented.
// MethodThrowingProperException();
// Should not break.
MethodThrowingInternalExceptionOrRatherContinuableError();
// Should execute, even if previously an internal framework error happened.
MethodNotThrowingException();
}
#endregion
#region ===== Framework methods, they are contained in a foreign dll =====
private static void MethodThrowingProperException()
{
// Something happened which should break execution of the
// application using the framework
throw new RealException();
}
private static void MethodThrowingInternalExceptionOrRatherContinuableError()
{
// Perform some stuff which might lead to a resumable error,
// or rather an error which should not break the continuation
// of the application. I.e. initializing a value which is
// already initialized. The point is to tell the application using
// this framework that the value is already initialized, but
// as this wont influence the execution at all. So its rather
// a notification.
throw new InternalFrameworkException();
}
private static void MethodNotThrowingException()
{
// Well, just do some stuff.
}
#endregion
}
}
Edit: I did try the example in the post I already linked above, and it works like a charm ... when using it in SomeMethod() only. I could theoretically implement this as I am wrapping all the methods that are called in SomeMethod() before exposing them to the final assembly, but I dislike this approach, because it will give my code unnessessary complexity.
When an exception is thrown, the execution flow is broken. You can catch the exception or not but you cannot "continue" after the exception is thrown.
You can split your logic into parts and continue to the next part when one throws an exception, though.
I'm not sure of a way apart from an AOP approach in this case. Given that you are unable to change SomeMethod() or any of the methods it calls, you will need to look at adorning the called methods like MethodThrowingInternalExceptionOrRatherContinuableError() with an aspect that catches the 'continuable' exceptions.
The aspect would effectively wrap the method call in a try{...} catch(InternalFrameworkException) (or similar catchable exception) block.
As you have already noted, you are unable to drop back into a method once it has thrown an exception, even if the caller catches the exception in a catch() block, so you need to inject into the methods you are calling, which an AOP framework like PostSharp will allow you to do.
I have solved similar problem by wrapping the calls to InternalFrameworkMethod() in try-catch(InternalFrameworkException) blocks and calling it somethig like InternalFrameworkMethodSafe() and then in SomeMethod call the treated InternalFrameworkMethodSafe().
void InternalFrameworkMethodSafe()
{
try
{
InternalFrameworkMethod();
}
catch(InternalFrameworkException e)
{
Trace.Write("error in internal method" + e);
}
}
void SomeMethod()
{
...
InternalFrameworkMethodSafe();
...
}
It may not work in your case if the internal framework is in wrong state and not able to continue.

position of the try catch statement

I have some code that currently looks somewhat like this:
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch
{
AllFineFunction();
}
}
private void SomeProblemFunction() { ... }
private void AllFineFunction() { ... }
As you can see, I'm currently wrapping the call to SomeProblemFunction around a try statement because that function could fail (it relies on an outside web service call).
My question is this: should the try statement be a) outside the problem function (like I have it now) or b) inside the problem function?
Thanks.
Typically you want to allow your exceptions propagate up to your application boundaries. You're only going to want to do one of a few things with your exception:
Wrap it
Replace it
Let it propagate
Update
From your question it seems that you are looking for a fault tolerant solution for your web service calls. This is a more complex problem than simply "where do I put my try-catch?" You would still place your exception handling at the application boundary, but there you would implement your fault tolerance strategy. This would need to have many considerations, including asynchronously calling your web service, number of retry attempts, etc. I would suggest doing a search for web service fault tolerance.
What you have is correct; see the MSDN example:
public class ThrowTestB
{
static void Main()
{
try
{
// TryCast produces an unhandled exception.
TryCast();
}
catch (Exception ex)
{
// Catch the exception that is unhandled in TryCast.
Console.WriteLine
("Catching the {0} exception triggers the finally block.",
ex.GetType());
// Restore the original unhandled exception. You might not
// know what exception to expect, or how to handle it, so pass
// it on.
throw;
}
}
public static void TryCast()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// Report that the finally block is run, and show that the value of
// i has not been changed.
Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
}
}
// Output:
// In the finally block in TryCast, i = 123.
// Catching the System.InvalidCastException exception triggers the finally block.
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}
As a rule of thumb I try and build code that focuses try catches to the exact spot the problem may occur.
That said both of your solutions are correct.
If it were my code I would do this
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch(Exception e)
{
Messagebox.Show(e.Message);
}
}
private void SomeProblemFunction() {
try{
web call
}
catch{
throw a specific exception related to this spot
}
}
private void AllFineFunction() { ... }
With this method you can easily create applications that handle a slew of very accurate exceptions
A fine question, I think. I'll attempt an answer.
If you want to recover within SomeProblemFunction, then it would make perfect sense to move the try...catch inside of that method. If, however, you are comfortable saying that if anything fails in SomeProblemFunction, then the whole thing is a failure, then keep it as you have it now and recover in (or throw from) MainFunction.
Thanks to the comment below, I'm adding some clarity. Depending on the specific exception that is being thrown within SomeProblemFunction, you may not have the ability to recover within that method. If you have a mixture of recoverable and non-recoverable, then it would be prudent to have the try...catch in both places.
The most important thing is that you NEVER catch an exception from which you cannot recover without throwing it on after doing your thing. It's tempting to add big broad catches (catch (Exception)) to avoid your app crashing during development, but it is never worth it. If those things make it into your production code, you've introduced a problem-solving and debugging nightmare.
In my opinion, there is no straight answer for this. The try catch is used to handle the exceptions that may occur. If your exception handling code is going in the main function then you should have the try catch in the main function. If your exception handling code in the problem function then you should add it to the problem function.
My preference though is to put it in both functions. If you put the try catch in the problem function, you can throw the exception and catch it in the main function. This always appear to other developers that the exception was thought of in that function and not missed handling it by mistake.
This depends on how severe this web service call failure would be.
Is it a failure that would prevent further processing of your code to run? If so, have no try/catch here, allowing it to propagate up to the guy who needs to know that this web service call failed. Optionally, you could still catch and throw a new exception with some more meaningful Exception type/ details.
Do you simply just want to re-try the web service call again if it doesn't work? IF so, then you have the try in the correct place; you just need to add a loop.
Is it not a big deal if this web service call fails? e.g. - will the rest of your code work OK? (I've found this to be uncommon). If so, leave the try/catch where it is, and log the error somewhere so that you're alerted.

Exception handling in method definition or call?

I was wondering if there is a right place to handle exceptions.
Should I handle it inside my method or should I handle it at the method call? Or does it matter at all?
I'm sorry, but I couldn't find anything about this (googling "exception handling scope" didn't returned what I was looking for).
Example:
// this way...
void readFile(string file)
{
try
{
/* do my stuff */
}
catch(Exception exception)
{
/* handle exception */
}
}
int main()
{
readFile(file);
}
// or this way?
void readFile(string file)
{
/* do my stuff */
}
int main()
{
try
{
readFile(file);
}
catch(Exception exception)
{
/* handle exception */
}
}
Thanks in advance.
In general you want to handle the error where it makes sense to do so.
If in your example above you want to try to read a file and if that fails then read a default file the you can handle it as in the first example.
If the readFile operation failing is vital to the rest of main() then you need to have the exception passed up to that so it can deal with whatever fallout is for readFile() failing and this would be as in your second example.
Of course you can always handle the error (or some possible exceptions) inside the method and rethrow or let some pass through or whatever.
Really though its your program flow that determines where your exception handling goes. Handle the exception where it makes sense to do so.
The first approach is usually better, since all the file stuff is handled by readFile and code calling readFile does not have to worry about file handling issues. You could however return a boolean from readFile telling the caller if the operation succeded:
bool readFile(string file)
{
try {
/* do my stuff */
return true;
} catch(Exception exception) {
/* handle exception */
return false;
}
}
If you can handle the exception, recover from it and continue, then you should do that immediately.
On the other hannd, if there is nothing sensible you can do to handle the exception then the best thing is to let the exception propagate up the call stack. Eventually code at the top-level will be forced to catch the exception and log it / show it to the user, or else the application will crash.
Only handle the exception if you actually plan on doing something unique in that particular circumstance (e.g. talking to a DB and a deadlock exception occurs you may wish to retry the DB operation). If you just want to do some generic exception handling action (e.g. log every exception) do it in the highest level possible (usually the UI) and don't clutter your code up with exception handlers everywhere - just let the exceptions bubble up.
The best practice is to let the upper levels handle the exception. Imagine that you are packing your low level file reader in a library and handling the exception there. You are not giving the users of your code the ability to handle the exception in the way that they desire.

Error info lost from worker thread

I would like to understand why the following behaviour happens and any ways to achieve what I need.
I have a main thread that spwans a backgorund worker to do some processing. I have a background worker completed even handler where I listen for any error. When there is an error I throw the error and allow it to float back to the main thread. I dont want to handle the error and show any message from the background worker.
But when the error is finally trapped in the main thread, I dont get to see the actual error message but I get an 'target invocation unknown' error. Would like to understand why and any ways to do such scenarios.
Comments:
Added Source Code Sample as requested.The reason why WCF was added because this logic is coded in a WCF service scenario. Hope it makes more sense now.
class ParentClass
{
static void main()
{
try
{
Thread t = new Thread(new ThreadStart(M1));
t.Start();
// ...
// ...
}
catch
{
// here I dont see the error as 'date time conversion'
// but see a generic error as I mentioned
}
}
static void M1()
{
try
{
Convert.ToDateTime("sss");
}
catch (Exception e)
{
// Here I see the error as 'error in date time conversion'
throw;
}
}
}
Thanks,
Mani
Without looking at code, it's hard to guess how you are passing the exception, but did you check the InnerException property of the Exception you receive. It may contain the information you are looking for. If there is no information, it could be that the code that is catching the exception and "floating" it may itself be generating an error.

top-level exception handling with event handlers in c#

I am currently asking myself some questions about exception handling and eventhandlers, and i hope some of you will give me some help.
I will start to explain what i would like to achieve in my c# application:
I have a top-level method (lets call it the main method). This method calls an asynchronous method (wich is called connect), which connect to a FTP server.
An EventHandler object is associated to this connection, and a "callback" method is called when the connection is successful.
I want to handle exceptions that can be launched during the whole process. So i would like to catch it in the top level method. It works fine for exceptions launched by the connect method (which is called inside the top level method).
However, it does not work for exceptions called inside the "callback" method: the top level method does not catch them and the execution fails.
What can I do to make these exceptions beeing caught by the top level method ? I don't want to handle these exceptions in the callback.
Take a look at how the Backgroundworker deals with this: the Exception is propagated to the Completed event handler.
I assume you have some form of State object that is passed to/from the delegate, that's where you can add such a property. And you will have to catch all exceptions in the thread, at the outermost scope. But 'handling' just means passing it along.
There is a standard pattern for the RunWorkerCompleted event, see this MSDN page.
Consider the below code fragment for wrapping all of your code in a global exception handler:
namespace MyClient
{
class Program
{
static void Main(string[] args)
{
try
{
bool isSuccess = SubMain(string[] args);
}
catch (Exception e)
{
HandleExceptionGracefully(e);
}
}
static bool SubMain(string[] agrs)
{
// Do something
}
static void HandleExceptionGracefully(Exception e)
{
// Display/Send the exception in a graceful manner to the user/admin.
}
}
}
Also, don't forget to make your error handling user-friendly.
There is an event handler in the Application class called ThreadException. This event will be fired whenever an exception is thrown an not caught anywhere in the current call stack.
Edited:
Sorry, I misread the question - I didn't realise that the "main" method in your example isn't the actual main method. In that case you may want to catch the exception inside the callback, but not handle it - instead simply pass it back up to the main method as part of the event args.
The BackgroundWorker in Winforms does something similar.
Thanks for your answers.
It seems that using the BackgroundWorker solve this problem.
I did not try it, because i chose to avoid this implementation burden. So I took away my asynchronous call and made my application behaving synchronously.
One tip for people using the Compact Framework instead of the full .NET Framework:
the BackgroundWorker is not available in CF, but a similar solution is provided by OpenNETCF (see the BackgroundWorker class in the Smart Device Framework).
A more convenient way to deal with this problem of top-level exception handling is to use delegates.
These c# delegates allow to call methods in a asynchronous way. And delegates allow also top-level exception handling. Indeed, exceptions thrown inside delegates are re-thrown on the original thread.
I don't know why i did not think about delegates before.
I hope it will help.
See these nice articles about delegates:
Article 1
Article 2

Categories

Resources