Exception in Async Delegate Causing Resource Cleanup in Others

T

Travis Parks

Hello:

I have group of independent jobs that I run in parallel using
asynchronous delegates. I am starting each task with code that looks
like this:

Action action = job.Run;
action.BeginInvoke((IAsyncResult result) =>
{
action.EndInvoke(result);
}, null);

I am expecting the call to EndInvoke to throw an exception if one
occurred. This is happening as expected. However, when it does, it
appears that other jobs start throwing exceptions complaining that
database connections are closed. Each job is responsible for creating
a new connection for itself. The jobs do not use any shared data, data
is transferred via a database. So synchronization isn't an issue.

I am wondering how the first exception is triggering the closing/
disposal of the connections in the other threads. Could this have
something to do with connection pooling? I was thinking that maybe the
first exception was killing the main thread, triggering some kind of
resource cleanup on the background threads.

Currently, I am handling this by capturing every exception that is
being thrown, and only throwing the relavent one. I can tell which is
relevant by looking at the type of the exception. The first exception
is a custom exception and all the others are
InvalidOperationExceptions (The Connection must be open...). However,
I would like to avoid the other exceptions entirely, since I don't
think they should be happening.

We are probably a release away from using .NET 4.0. I am wondering
whether I should just use my current technique until I can start using
the TPL.

Is there some underlying mechanism that calls dispose on background
threads? It just seems weird to me that independent jobs would have
this problem. It is even happening when the main thread captures and
swallows these exceptions.

Thanks for any insight. I will try to create a simple example that
reproduces the issue.

Thanks,
Travis Parks
 
T

Travis Parks

I'm starting to think this has something to do with Oracle not knowing
how to write code. :)

I wrote a small example using SqlConnection and I can't reproduce the
issue.
 
T

Travis Parks

Can you be more specific?  In particular, do you start multiple delegate
invocations with the same delegate variable (e.g. "action")?  If so,
then the callback methods are all using the same variable, and the value
in that variable could be the same for all, depending on thread
scheduling.  Then an exception in one will look like an exception in
all, if the one that causes the actual exception happens to be the one
assigned to the variable when the others complete.



I would think it would depend on the exception.  If a pooled connection
is itself getting reset, then I suppose that could affect every thread
using the same connection.  But if it's some exception unrelated to the
connection, then I would think that even closing the connection from the
thread that threw the exception shouldn't affect the other threads
(since closing the pooled connection shouldn't actually close the
connection).

Per your follow-up speculation, I suppose it's possible that there's a
problem with Oracle's implementation.  But to demonstrate that
conclusively, I think you would need to swap in a non-Oracle DB provider
for your real-world code and see if the problem goes away.  Just because
you can't reproduce it with a small example doesn't mean it's a bug in
Oracle's code.  It could just be that the example just doesn't include
the particular bug in your own code that's causing the problem.

Of course, if you can reproduce the problem in the small example using
Oracle and then it doesn't happen using some other provider, then that
does suggest it's an Oracle problem.  But even there you will want to be
careful about drawing conclusions, because it's possible for there to be
subtle differences.  For example, perhaps the SqlConnection object is
pooled differently, or has some additional feature that recovers from
client code errors in some way.

Pete

I've been struggling to reproduce the bug at home or come up with a
decent example. I will need to wait until I get back to work on Monday.
 

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