Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IAsyncResult -- Exception Handling

349 views
Skip to first unread message

John Smith

unread,
Nov 29, 2008, 12:48:19 AM11/29/08
to
Hello,

Background: Deserialization of a message body must be specified with late
binding and the code must be able to handle messages in the queue that are
unexpected (for whatever reason).

((XmlMessageFormatter)oMsgQue.Formatter).TargetTypeNames = new string[] {
"Loxias.TMSMQ_CDR,TMSMQ_CDR,Version=2.0.0.0" };

How do I catch the exception that occurs in the IAsyncResult thread, since
it (the MessageQueue.BeginReceive Method), does not handle the exception,
and an unhandled thread exception causes application termination:

IAsyncResult mqAsyncResult = oMsgQue.BeginReceive(new TimeSpan(1, 0, 0),
oMsgQue);
// . . . snip . . .
System.Messaging.Message mqMsg =
((MessageQueue)e.AsyncResult.AsyncState).EndReceive(e.AsyncResult);

// . . . application crash . . .
try
{
object oBody = mqMsg.Body;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

// and . . . not even this will catch the exception for reporting purposes:
AppDomain.CurrentDomain.UnhandledException += HandleError;
// . . .
static public void HandleError(Object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
Console.WriteLine(ex.Message);
}

I am fairly certain that in the end... I will have to use blocking
synchronous message queue calls :-(

Frank Boyne

unread,
Nov 30, 2008, 3:30:07 PM11/30/08
to
"John Smith" <som...@microsoft.com> wrote in message
news:00BBD2D3-FF00-4BCE...@microsoft.com...

> How do I catch the exception that occurs in the IAsyncResult thread,
> since it (the MessageQueue.BeginReceive Method), does not handle the
> exception, and an unhandled thread exception causes application
> termination:

You handle it the usual way - with a try - catch block.

> // . . . snip . . .
> System.Messaging.Message mqMsg =
> ((MessageQueue)e.AsyncResult.AsyncState).EndReceive(e.AsyncResult);
>
> // . . . application crash . . .
> try
> {

The mqMsg assignment is outside of your try - catch block. If it throws
an exception your try-catch doesn't do you any good.

The AsyncState property is user defined. Assuming you haven't set
AsyncState in some way, it will be null. casting a null to MessageQueue
will still be null and calling null.EndReceive will throw a Null
Reference Exception. A try - catch block would catch that exception if
there were one around the call.

Assuming we are inside a Receive Completed event handler, use the sender
parameter (not the e parameter) to access the queue. Something like
this for example...

MessageQueue mq = null;
System.Messaging.Message m = null;

try
{
// Connect to the queue.
mq = (MessageQueue)sender;

// End the asynchronous receive operation.
m = mq.EndReceive(e.AsyncResult);

... etc ...

}
catch (Exception ex)
{
Console.WriteLine("exception: {0}", ex);
}


John Smith

unread,
Dec 1, 2008, 6:05:25 PM12/1/08
to
Thank you for helping me.

> The AsyncState property is user defined. Assuming you haven't set
> AsyncState in some way, it will be null. casting a null to MessageQueue
> will still be null and calling null.EndReceive will throw a Null Reference
> Exception. A try - catch block would catch that exception if there were
> one around the call.

I must admit to having copied that code and did not read the description of
the AsyncState property, simply because everything works just fine if the
appropriate formatter is found.

Having read your posting, I used the debugger and found that the AsyncState
property is not null as documented and I only mention this to provide true
information and not to snip back at a person trying to help me. That said,
I further simplified my investigation by making the code change you
suggested.

I still cannot trap the exception, using the following...

static public void HandleError(Object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
Console.WriteLine(ex.Message);
}


AppDomain.CurrentDomain.UnhandledException += HandleError;


try
{
mqMsg = oMsgQue.EndReceive(e.AsyncResult);


object oBody = mqMsg.Body;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}


You may easily reproduce this issue by sending a message with a class-typed
body and then receive it using the following formatter:

((XmlMessageFormatter)oMsgQue.Formatter).TargetTypeNames = new
string[] { "System.String,mscorlib" };


Effectively, I cannot catch an handle the exception and therefore cannot use
it in a production environment because any unexpected message received would
crash my process and it would be a nightmare to find the cause (if it were
not already known).

Frank Boyne

unread,
Dec 14, 2008, 9:24:52 PM12/14/08
to
"John Smith" <som...@microsoft.com> wrote in message
news:CB726D2F-E7F6-4C53...@microsoft.com...

> Having read your posting, I used the debugger and found that the
> AsyncState property is not null as documented

It's hard to be absolutely certain about this because I don;t have
access to Microsoft's sources for MSMQ. I can't say for certain that
MSMQ never sets AsyncState. What I can say is that when I write a
simple test case and use the debugger to examine AsyncState it is null.

It may be that your program is setting AsyncState somehow (although off
hand I can't think how I would do that). It may be that your program's
calls on BeginReceive etc. somehow cause MSMQ to set AsyncState.

> I only mention this to provide true information and not to snip back
> at a person trying to help me.

No problem. The more information we all share the more likely we are to
figure out what is going on.


> That said, I further simplified my investigation by making the code
> change you suggested.
>
> I still cannot trap the exception, using the following...
>
> static public void HandleError(Object sender,
> UnhandledExceptionEventArgs e)
> {
> Exception ex = (Exception)e.ExceptionObject;
> Console.WriteLine(ex.Message);
> }
>
> AppDomain.CurrentDomain.UnhandledException += HandleError;

Did you try trapping the exception wit a try-catch block? That works
for me.

I would not expect UnhandledException to be much use in this case.
Remember that UnhandledException is only invoked "... if the entire
stack for the thread has been unwound without finding an applicable
exception handler...".

Again, we can't be sure because we can't see Microsoft's sources but I'd
be willing to bet that the Microsoft code to invoke the receiveCompleted
Event handler has an exception handler defined to make sure that the
user provided event handler logic does not disrupt the proper delivery
of the event to other event handlers that may have been registered.

> Effectively, I cannot catch an handle the exception and therefore
> cannot use it in a production environment because any unexpected
> message received would crash my process and it would be a nightmare to
> find the cause (if it were not already known).

Try-Catch works for me. I'm pretty sure it will work for you too.


0 new messages