views:

191

answers:

3

I found a decent looking example of how to call a delegate asynchronously with a timeout... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx. In summary it uses WaitOne with a timeout to determine if the call does not return before the timeout expires.

I also know that you should have an EndInvoke to match each BeginInvoke.

So what happens if the wait timeout expires? We (presumably) DON'T want to call EndInvoke as that will block. The code can go on to do 'other things', but have we leaked anything? Is there some poor thread someplace blocked waiting for a return that's never going to happen? Have we leaked some memory where the result-that-will-never-return was going to be placed?

+2  A: 

You need to call EndInvoke().

Here is a link talking about what happens with EndInvoke():

http://stackoverflow.com/questions/532722/is-endinvoke-optional-sort-of-optional-or-definitely-not-optional

Here is a link to the article in the accepted answer.

We had all been talking about the 'fire and forget' technique with asynchronous delegate invocation in various public forums. Many DevelopMentor instructors had written articles and example code showing the technique, and we had all described it in class. And of course it was in Don's book by then too. So when Microsoft eventually remembered to let the outside world know that this technique is not in fact legal, it was rather astonishing.

An MSDN link on the asynchronous pattern.

Kevin
+1  A: 

I think this post talks about it very well:

From the post:

You can't terminate an executing async delegate if it's not your thread, but you can if it is. If you use the common BeginInvoke type methods, you get a thread pool thread managed by the framework. If you use the Thread() class you get you own thread to manage, start, suspend, etc. as you like.

Developing asychronously requires that one decide who will manage the threads. The many different methods that execute asynchronously are using the ThreadPool threads behind the scenes.

Since you can't/shouldn't terminate a thread pool thread then you must design you code to communicate with the thread so that it can exit. The MSDN examples for the BackgroundWorker component demonstrates this kind of communication.

Sometimes your code may have the thread blocking waiting for IO. Here you would normally use a multiple object wait instead, waiting for IO or for a ManualResetEvent.

So in short, youll need to find a way to manage the threads yourself if there is a possibility of timing out and you want the thread to end.

SwDevMan81
+1  A: 

You will leak the resources held by the thread. There will be various bits of .NET remoting plumbing objects like the AsyncResult. Several unmanaged handles associated with the thread. All peanuts compared to the one megabyte of virtual memory address space you'll leak, held by the thread stack.

You cannot abort the thread in any way, the leak is permanent. When you have to deal with badly behaving code like this, your only good resource is to run it in a separate process so you can get Windows to clean up the shrapnel when you shoot the process in the head with Process.Kill(). Even that is not guaranteed, these kind of freezes tend to be associated with misbehaving device drivers. Process.Kill won't terminate a device driver thread. Easy to see: trying to abort the process with Taskmgr.exe will leave it running with one Handle. You have some hope if that doesn't happen.

Hans Passant