C # - exception throwing issue in AsyncCallback

The following code is pretty clear, and my question is very simple:
Why does the AsyncCallback "HandleConnect" method not propagate the exception to the "Connect" method and how to distribute 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 think this is pretty normal behavior. But I would appreciate a comprehensive explanation of why this is happening and what is happening just behind the hoods.

2 - Is there any (quick and easy way) to throw an exception through my application?

forewarning I know that many dudes here are very critical, and I expect comments: β€œWhy don't you put the ManageException directly in theβ€œ HandleConnect ”method. Well, to make the long story short, let's just say:β€œ I got my reasons. ” I just posted a sample code here, and I want to extend this exclusive path further than this and do much more than shown elsewhere in the "N-upper" code.

EDIT
As a comment on a comment, I also tried this earlier, 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 creating an event handler to which each corresponding code logic is signed.
Thus, the exception is not just swallowed, but simply hits, but a notification is sent.

  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. } 

It's a little crooked, but it works great

+4
source share
3 answers

When you use BeginConnect , the connection is asynchronous. You get the following chain of events:

  • Connect β€œsends” a connection request through BeginConnect .
  • Connect returns a method.
  • The connection is in the background.
  • HandleConnect is called by the wireframe with the connection result.

When you reach step number 4, Connect already back, so the try-catch block is no longer active. This is the behavior that you get when using asynchronous implementations.

The only reason you would get an exception caught in Connect is if BeginConnect cannot start the background connection task. This can be, for example, if BeginConnect checks the provided arguments before starting the background operation and throws an exception if they are incorrect.

You can use the AppDomain.UnhandledException event to catch any unhandled exceptions in a central location. Once the exception reaches this level, any form of recovery is probably difficult to achieve, since the exception can be from anywhere. If you have a recovery method, catch the exception as close to the source as possible. If you are only registering / informing the user by catching centrally in place, it is often better.

+5
source

One option is to use AsyncWaitHandle with your existing code.

For better exception handling, you will either have to use an event-based programming model or modify your code to use the BackgroundWorker component, which supports a reporting error from the workflow to the main thread.

This topic has several discussions and articles at the following links:

http://openmymind.net/2011/7/14/Error-Handling-In-Asynchronous-Code-With-Callbacks/

MSDN example: http://msdn.microsoft.com/en-us/library/ms228978.aspx

+2
source

In addition to what Anders pointed out, it's probably a good idea to read this:

http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

and see how you can pass the callback method to the BeginConnect asynchronous call (if one exists) using something like AsyncCallback, where you can get the delegate and call EndInvoke in the catch try block.

eg:.

  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 
+1
source

Source: https://habr.com/ru/post/1381297/


All Articles