Handling exceptions in Socket Callbacks

G

Guest

Hi,
I am having some problem with callback used in socket implementation.
private static void Connect(string strPrtrIPAddr, int intPrtrPort, ref
Socket rsocClient)
{
try
{
// Create remote end point.
System.Net.IPAddress IPAddress = System.Net.IPAddress.Parse(strPrtrIPAddr);
System.Net.IPEndPoint IPEndPoint = new System.Net.IPEndPoint(IPAddress,
intPrtrPort);

// Create a TCP/IP socket.
rsocClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);

// Connect to the remote end point.
rsocClient.BeginConnect(IPEndPoint, new AsyncCallback(ConnectCallback),
rsocClient);

// Signal the connection event to wait.
mevtConnectDone.WaitOne();
}
catch(Exception objException)
{
throw objException;
}
}

private static void ConnectCallback(IAsyncResult IResult)
{
try
{
// Retrieve the socket from the state object.
Socket socClient = (Socket) IResult.AsyncState;

// Complete the connection.
socClient.EndConnect(IResult);

// Signal that the connection has been made.
mevtConnectDone.Set();
}
catch(Exception objException)
{
mevtConnectDone.Set();
throw objException;
}
}

Please check the above two methods. Callback throws an error at EndConnect
but it is not propogated to the parent function. How to solve this problem.
Please help me asap. Thanks in advance.
 
R

RockinFewl

faktujaa,

The exception propagation doesn't work because, in contrary to what you
think, your Connect() method is NOT a parent function of your
ConnectCallback(). The asynchronous Delegate mechanism uses an other
thread to eventually run the callback on, so basically your two
functions are highly independent, and surely not on the same call stack.

In your case the solution is simple though.
I see you use asynchronous methods, yet try to mimic a synchronous
behaviour (with the mevtConnectDone event). This makes everything
unnecessary complex, and induces also your particular problem. I don't
know what your future plans with this code are, but I'd ditch the
asynchronous approach here. You'd get this:

private static void Connect(string strPrtrIPAddr, int intPrtrPort, ref
socket rsocClient)
{
try
{
// Create remote end point.
System.Net.IPAddress IPAddress = System.Net.IPAddress.Parse(strPrtrIPAddr);
System.Net.IPEndPoint IPEndPoint = new System.Net.IPEndPoint(IPAddress,
intPrtrPort);

// Create a TCP/IP socket.
rsocClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);

// Connect to the remote end point SYNCHRONOUSLY.
rsocClient.Connect(IPEndPoint);
}

catch(Exception objException)
{
throw objException;
}

}

No callback applies.

Code goes untested, so forgive me the occasional typo.

Hope his helps,
Koen.
 
R

RockinFewl

Hi faktujaa,

You're correct the asynchronous socket methods give more opportunities
in creating performant code. There aren't many occasions I use
synchronous ones myself.
However, I'd consider this particular Microsoft article as example code.
Using an asynchrounous BeginConnect() to avoid blocking, yet
immediately do a WaitOne to _do_ blocking, doesn't make much sense.
Typically, you'd do other, useful things instead of just blocking
waiting for a completion event: you may attempt to begin some more
connections, or handle existing ones for instance.

Anyway, I see you feel intuitively your Connect() method can't possibly
be the place to catch exceptions thrown in ConnectCallback(). If you
remove the WaitOne in you original code, it's expectable Connect()
finishes BEFORE ConnectCallback() finishes (or even starts perhaps).
Again, this illustrates that the two method calls are not on the same
call stack.

I always handle exceptions in callbacks in the callback itself. Apart
from some complicated (unseen) approach to transfer exceptions as
objects to another thread and rethrowing it there, I see no other option.

Koen.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top