exception handling with events

N

Natalia DeBow

Hi there,

I am working on an client-server app, where the client asynchronously issues
a request for the server to perform some action and the server is supposed
to notify the client when the action was performed and send the data back by
raising an event.

My question is how do I catch exceptions on the client side that can
potentially be thrown while the server is trying to perform an action, since
the client used BeginInvoke to spawn a worker thread when making this
function call. Also, I've read that for every BeginInvoke, there should be
an EndInvoke to release the worker threads back to the thread pool.
How/where would I use EndInvoke in my scenario? I really don't have a
callback right now, since I am using the event handling method and the data
is being returned via the EventArgs object in the event and not using the
result of the AsyncResult.

What would be the best approach to handle exceptions on the client side with
events and where would I include EndInvoke?

Client code:
-----------------
public class Client
{...
....
public void MakeServerDoAction(...)
{
try
{
server.fireEvent += new EventHandler(OnEventFired);
server.DoAction.BeginInvoke (param1, param2, null, null);
}
catch (Exception e)
{...
}
}

public void OnEventFired(object sender, EventArgs e)
{...
....
// display info from EventArgs on the UI.
}
}
Share data:
-------------
public class DataTypes
{
public event EventHandler fireEvent;
public delegate void EventHandler(object sender, EventArgs e);
}

Server code:
-------------------
pubic class Server
{
public void DoAction(int param1, double param2)
{
// do some stuff
InvokeDone(data);
}
internal void InvokeDone(object data)
{
if (fireEvent != null)
foreach (Delegate del in fireEvent.GetInvokationList)
{
try
{
....
}
catch (Exception e)
{...
}
}

Thanks so much in advance,
Natalia
 
D

DanGo

You must call EndInvoke to avoid memory leaks.
The good news is that any exception that your DoAction threw will be
thrown when you call EndInvoke (that's so cool!)

So when shoud you call EndInvoke?

The second to last argument to BeginInvoke is an AsyncCallback that
will be called when your function has completed. You can use this to
call EndInvoke.

Of course you need the delegate to fire EndInvoke. The delegate is
hidden inside the argument passed to your AsyncCallback method.
IAsyncResult does not contain the delegate but it can be safely cast to
AsyncResult (in the System.Runtime.Remoting.Messaging namespace) this
contains the delegate which
you can then use to call EndInvoke.

You should call EndInvoke in a try/catch block to catch any exceptions
your asynchronous method threw.

Your AsyncCallback executes on the thread pool thread so don't directly
access UI from the callback (use control.BeginInvoke).

Instead of :
server.DoAction.BeginInvoke (param1, param2, null, null);

use :
Server.DoAction.BeginInvome(param1, param2, new
AsyncCallback(ActionCompleted), null);

void ActionCompleted(IAsyncResult iar)
{
System.Runtime.Remoting.Messaging.AsyncResult ar = iar as
System.Runtime.Remoting.Messaging.AsyncResult;
if (iar != null)
{
EventHandler eh = ar.AsyncDelegate as EventHandler;

if (eh != null)
{
try
{
eh.EndInvoke();
}
catch(Exception ex)
{
// the exception thrown by Server.DoAction
// process the exception
// If you want to display it on the ui make sure to use
Control.BeginInvoke since this routine is executing on the thread pool.
}
}
}
}
 
N

Natalia DeBow

Hi DanGo,

Thanks so much for your response! Your solution is viable, however, it
requires me to create a callback method "Action Completed" that I really
don't need for anything other than exception handling. From what I've
read, I should only use callbacks if I need to get to the result of the
asynchronously executed method. In my case, I don't care about the
result, since the valuable data is being returned via event handling
mechanism. So, this poses another question, is there any other way to
catch exceptions from the worker thread other than creating a callback
and calling EndInvoke from it? Is there any other place where I could
call EndInvoke from (for instance, from the same method that called
BeginInvoke) and what would be the drawbacks of this approach?

Thanks again,
Natalia
 

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

Similar Threads


Top