Cancel an asynchronous call (IAsyncResult) - c#

I am programming in .net WPF.
I have a (third party) API which implements the Begin/End asynchronous call pattern. The BeginWork() function returns an IAsyncResult.
However, there is no apparent method to cancel/abort the call, once done.
Is there a way to have such a job stopped? If this requires the library author to provide explicitly for a cancel method, what is a way to kill this job, even ungracefully? I really need to be able to stop it somehow, as a single job may take hours to complete!
Thanks!

If the implementation does not include specific code allowing for cancellation, then it is quite likely that you can't cancel it. Not everything can be logically cancelled cleanly, especially if it involves external resources. But also if the code to cancel it simply hasn't been written.
.you could try randomly killing threads, but this will doom your process - basically this would be the same as deciding to kill the entire process half way through. It will stop the work, but it could leave things in a complete mess if it isn't transactional.
If I was you I would (one of):
ask the 3rd party for a supported cancellation API
don't start it unless you are sure

Related

What would be a use case for Thread.Sleep(Timeout.Infinite)?

I happened to lay my eyes on an intellisense tool tip regarding the parameter passed to System.Threading.Thread.Sleep(int millisecondsTimeout), saying something like "(…) Specify System.Threading.Timeout.Infinite to block the thread indefinitely". And I am intrigued.
I can understand why one might include short inactive delays within a possibly endless loop, thus yielding processing power to other executing threads when no immediate action in the sleeping thread is required, although I typically prefer implementing such delays with EventWaitHandlers so that I can avoid waiting a full sleeping delay if I signal the thread to gracefully end its execution from a different thread.
But I cannot see when I might need to suspend a thread indefinitely, and in a way that, as far as I can tell, can only be interrupted through a rather ungraceful Thread.Abort()/ThreadAbortException pair.
So what would be a working scenario where I might want to suspend a thread indefinitely?
It is a pretty long story and I have to wave my hands a bit to make it understandable. Most programmers think that Thread.Sleep() puts the thread to sleep and prevents it from executing any code. This is not accurate. Thread.Sleep(Infinite) is equivalent to Application.Run(). No kidding.
This doesn't happen very often in real life, it is mostly relevant in custom hosting scenarios. Getting code to run on a specific thread is in general an important feature to deal with code that is not thread-safe and the major reason why Application.Run() exists. But Windows exposes another way to do at a much lower level, the underlying api for this is QueueUserAPC(). The .NET analogue of this function is BeginInvoke().
This requires the thread to co-operate, just like it does when it calls Application.Run(). The thread must be in an "alertable wait state", executing a blocking function that can be interrupted. The CLR does not execute the sleep by itself, it passes the job to the CLR host. Most hosts will simply execute SleepEx(), passing TRUE for the bAlertable argument. The thread is now in a state to execute any requests posted by QueueUserAPC(). Just like it will be when it is actively executing inside the Application.Run() dispatcher loop.
The kernel feature is not otherwise exposed at all in the framework. It is the kind of code that is very hard to get right, re-entrancy bugs are pretty nasty. As most programmers that were bitten by Application.DoEvents() or a poorly placed MessageBox.Show() can attest. It is however a valid scenario in a custom hosting scenario. Where the host can get C# code to run on a specific thread, using this mechanism. So it is possible to pass Infinite because the designers did not want to intentionally disable this scenario. If this is made possible at all by the host author then they'd let you know about it. I don't know of a practical example.
More practically, you do use this feature every day. It is the way that System.Threading.Timer and System.Timers.Timer are implemented. Done by a thread inside the CLR which is started as soon as you use any timer, it uses SleepEx(INFINITE, TRUE) at its core.
You can use .Interrupt() to wake a sleeping thread (causing ThreadInterruptedException in the code that was calling .Sleep(), which can be caught and handled), so this provides a mechanism to say "sleep until someone prods you". I'm not saying it is necessarily the best mechanism for this, but: it may have uses for you.

Is it good practice to always wait on a task to complete?

Sorry if it is a dumb question. I'm confused about the wait() and its variants in regards to the task parallel library.
Every single example I've seen waits on tasks to complete - is this considered good practice?
My scenario is this, that I'm developing a windows service that will run continuously. I would like to engage a number of tasks, but I don't care if they will run to completion - I will set a cancellation-token with an expiration, that will throw an error if something goes awry. So I don't see the need for a wait-to-complete, but every darn example uses it...
It really depends on what your situations needs. If for instance, you want to launch a sub process to do a procedure, say for instance, fire off an email in parallel you can do without waiting.
However, if you will need to act upon what ever result or structure which is affected by some behavior you will need to wait.
If your tasks are self contained and do not interact and/or depend on each other, then I do not see why you would need to wait.
You only need to wait on a task if the code that is waiting requires the output of the task before it can proceed. If you don't need that output, don't wait.

Task equivalent that can be killed at once

I want to run a long running opeartion in the background.
The requirements are:
The operation should run async to the calling thread.
The calling thread can wait on the operation to complete and obtain its result
Upon timeout, the operation should be aborted at once.
I would have used task, but there is no mechanism that I know of to kill the task dead cold.
Cancel token is not suitable for me, I would only kill a task if it gets stuck for unknown reason - (a bug) , this is a fail-safe mechanism.
Needles to say if the task is stuck, there is no use in requesting cancel.
Same goes for BackgroundWorker.
Is there anything more elagent than using a shared object between the calling thread and a background thread?
There is nothing more elegant than using a shared object, since using a shared object is the elegant way of doing this :)
You cant provide a generic way of killing a task safely: Since the killer thread does not have any clue of what the killee is doing when trying to kill it, this would potentially leave your object model in a "corrupted" state.
Thread.Abort() has been created to do that the cleanest way possible: By throwing an exception (which allows "finally" statements to dispose used resources, or running transactions disposal on killed thread). But this method can make the code throw an exception in unexpected location. It is highly not recommended.
nb: Thread.Abort() does not work in any case (example: wont work if your thread is running native code via a P/Invoke for instance)
Thus, the elegant solution is to write clean code, which can decide when it wants to be killed (via a cancellation token).
nb2: The ultimate "Thread.Abort()" which will work in any case, and which which will keep things isolated: Create a new AppDomain, run your killable code in this AppDomain (via remoting), and call AppDomain.Unload() when you want to stop everything.
This is a quite extreme solution, though.
The only way to kill a thread 'dead cold' that I know of is Thread.Abort, however, you will see a lot of answers to this related question, Killing a Thread C#, indicating that it is generally bad practice to use it, except in rare occasions.
Another option is to avoid trying to kill the task dead cold and implement better error handling in your task such that it gracefully handles exceptions and situations where it 'gets stuck'.

How do I make a .NET 4 thread wait for asynchronous requests to finish?

I am using HttpWebRequest.BeginGetRequest() to make 500 asynchronous HTTP requests from a single method. I would like that method to wait until I get a response from all the requests or they timeout.
What is the best way to do this?
I'm currently wrapping the asynchronous calls within a List of Task objects to use Tasks.WaitAll(), but I don't want to go too far down the rabbit hole before I know that this is a good solution.
Any ideas?
EDIT
I implemented counters, and they work, but I'm curious about using delegates like shown on this page.
Multi-threading and Async Examples
Has anybody done something like this before? Is it overkill?
I'm currently wrapping the asynchronous calls within a List of Task objects to use Tasks.WaitAll()
This is a fairly clean solution if you truly want to force these "tasks" to synchronize and block at this point. This is the main rationale behind Task.WaitAll(), and is nice since it (optionally) allows you to cancel the blocking operation after a timeout, if you so choose.
Personally I wouldn't block the thread, it defeats the purpose of the async model.
If I absolutely had to wait for these web requests to finish before continuing I would instead keep a counter that is incremented each time you get called back on a successful or failed request.
Check the counter on each callback and if it has hit your desired count then let the thread continue...
This way you can also keep your UI nice and responsive and perhaps update a counter/progress bar - Even if you're not kicking these off on the UI thread it's nice to provide some visual feed back tot he user about what is going on.

How to Purge a ThreadPool? [Microsoft System.Threading.ThreadPool]

Is it possible to purge a ThreadPool?
Remove items from the ThreadPool?
Anything like that?
ThreadPool.QueueUserWorkItem(GetDataThread);
RegisteredWaitHandle Handle = ThreadPool.RegisterWaitForSingleObject(CompletedEvent, WaitProc, null, 10000, true);
Any thoughts?
I recommend using the Task class (added in .NET 4.0) if you need this kind of behaviour. It supports cancellation, and you can have any number of tasks listening to the same cancellation token, which enables you to cancel them all with a single method call.
Updated (non-4.0 solution):
You really only have two choices. One: implement your own event demultiplexer (this is far more complex than it appears, due to the 64-handle wait limitation); I can't recommend this - I had to do it once (in unmanaged code), and it was hideous.
That leaves the second choice: Have a signal to cancel the tasks. Naturally, RegisteredWaitHandle.Unregister can cancel the RWFSO part. The QUWI is more complex, but can be done by making the action aware of a "token" value. When the action executes, it first checks the token value against its stored token value; if they are different, then it shouldn't do anything.
One major thing to consider is race conditions. Just keep in mind that there is a race condition between cancelling an action and the ThreadPool executing it, so it is possible to see actions running after cancellation.
I have a blog post on this concept, which I call "asynchronous callback contexts". The CallbackContext type mentioned in the blog post is available in the Nito.Async library.
There's no interface for removing a queued item. However, nothing stops you from "poisoning" the delegate so that it returns immediately.
edit
Based on what Paul said, I'm thinking you might also want to consider a pipelined architecture, where you have a fixed number of threads reading from a blocking queue (like .NET 4.0's BlockingCollection on a ConcurrentQueue). This way, if you want to cancel items, you can just access the queue yourself.
Having said that, Stephen's advice about Task is likely better, in that it gives you all the control you would realistically want, without all the hard work that rolling your own pipelines involves. I mention this only for completion.
The ThreadPool exists to help you manage your threads. You should not have to worry about purging it at all since it will make the best performance decisions on your behalf.
If you think you need tighter control over your threads then you could consider creating your own thread management class (similar to ThreadPool) but it would take a lot of work to match and exceed the functionality that ThreadPool has built in.
Take a look here at some of the ThreadPool optimizations and the ideas behind it.
For my second point, I found an article on Code Project that implements a "Cancelable Threadpool", probably for some of your own similar reasons. It would be a good place to start looking if you're going to write your own.

Categories