Cancel/Abort a Task in C# - c#

I have a program in C# which does some services calls.
I need to add some code in this program in order to be able to stop these services calls if I click on a button (winform) [For example, if the call is too long and the user is bored].
The difficulty is that I can't modify the blocks of code which do the calls.
In order to do so, I've planned to do some Interception with the Unity Framework.
I would like to create a Task each time I enter a service-call block of code. Then, cancel this task if the user clicks on my Button.
I've looked about CancellationToken but the problem is that I can't modify the calls-blocks, so I can't do if(ct.IsCancellationRequested) or ct.ThrowIfCancellationRequested();
Same thing for the AutoResetEvent & ManualResetEvent.
The calls are not always asynchronous and made with a cancellationToken, so catching OperationCanceledExceptionis, I think, impossible.
I've also looked about using Threads and do some Thread.Abort() but this method seems to kill puppies each time someone calls it.
Here is a sample of my current program (the Interception is not implemented yet, I want to test it on a single call first) :
private void Test()
{
Task.Factory.StartNew(MyServiceCallFunction); // How to cancel the task when I press a button ?
}
// Can't touch the inside of this function :
private void MyServiceCallFunction()
{
// Blabla I prepare the datas for the call
// Blabla I do the call
}
How can I do that ? (I'm not obliged to use a task)
Thank you,

The "correct" way to do it is to used CancellationTokens but since you can't modify the running code the only other way is to kill the puppies and use Thread.Abort()
Something like:
Thread t;
Task.Factory.StartNew(() =>
{
t = Thread.CurrentThread;
MyServiceCallFunction();
});
t.Abort();

Very Interesting question. Of course you cannot do anything when the third party call is doing TPL; in your case it is MyServiceCallFunction().
I have been in the similar situation where this blog post has helped me: https://social.msdn.microsoft.com/Forums/vstudio/en-US/d0bcb415-fb1e-42e4-90f8-c43a088537fb/aborting-a-long-running-task-in-tpl?forum=parallelextensions
(read: Stephen Toub - MSFTMicrosoft (MSFT) comments)
He has mentioned this solution:
int Test(CancellationToken token)
{
Thread currentThread = Thread.CurrentThread;
using (token.Register(currentThread.Abort))
{
MyServiceCallFunction()
}
}
Also replace Task.Factory.StartNew (...) with Task.Run(...) ; same, infect latter is stronger, but better readable.

Related

Create a Listener to Stop a Method Until Custom Callback Completes

I would like to stop a method until a custom delegate provides a callback from one method to a listener in another in Xamarin.Android, but I am having a lot of trouble understanding the implementation of such a listener.
I have only tried to understand how this could be done, but I'm stuck on how the delegate would be constructed and called.
Let's say that I want this MainActivity method to stop
public async override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
//how can I create a listener to stop this method until callback from OnPause?
//await a delegate task?
}
and await another method inside a Fragment:
public override void OnResume()
{
base.OnResume();
//I'd like to implement a delegate here to notify the OnWindowFocusChanged that OnResume method has been invoked
//what would be the construction of such?
}
How could I do that?
From my research, I believe I would need to create a delegate task, and then await it's return in OnWindowFocusChanged. However, I am confused about the implementation of such a solution. If anyone could provide even a very basic pseudo-code example, it would help me out a lot.
EDIT: I changed OnPause to OnResume because that's more useful for understanding what I'm trying to do. The below answer references OnPause, but those two are extremely similar methods anyway.
Here is an example that almost does what I'm trying to do; except instead of starting my method when OnResume is invoked, OnWindowFocusChanged stops for 10000ms. So basically, I'd like to replace the timer with a custom delegate (similar to an event) task that returns when Fragment.OnResume is invoked.
public async override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
//we won't pass this line for 10000ms; how to replace with Task return?
await WaitHere();
}
async Task WaitHere()
{
System.Threading.Thread.Sleep(10000);
}
You could try Task.Run method like:
await Task.Run(() => OnPause());
This would basically create a new thread or use the one you are on and schedule everything after this line as a continuation. So yes, the method would kinda stop, but unless you are on some GUI thread (not to block) or you run some IO task this is unnecessary.
I do not really understand what you are trying to achieve, but you might try to create new OnPauseAsync method that would return Task to get some result from the method when it finishes. This way you would get sequential like mechanism that doesn't block.
If you want to run those methods truly in parallel, but stop execution of OnWindowFocusChanged unitl something hapens in OnPause you should use bare Threads and some synchronization primitives like Mutex or Barrier. Then you would be able to make "main" thread wait until something happens (but it would block! beware). About those fellas you can read more here : LINK_WITH_FOCUS_ON_BARRIER
I am not really sure I got your intentions right, but I hope it helps somehow in the end.
To review:
if you just want to wait for the completion of OnPause and it does only CPU heavy things and you are not on UI thread - do not do anything as there is no profit in using threads etc.
if onPause does some IO heavy things you can use:
Tasks - potentially executed on one thread and doesn't block, control is returned to OnWindowFocusChanged AFTER onPause finishes completely.
Threads - if you want to run some parallel (two threads guaranteed) computations and wait for onPause to signal AT SOME POINT of execution to its caller that it might proceed, you can use e.g Barrier - but beware as this is the most complex solution from programmers perspective and it blocks if you are on UI thread.

AutoResetEvent.WaitOne() cause deadlock

I'm writing a application with a critical region.
And I decide to use AutoResetEvent to achieve mutual exclusion.
Here's the code
public class MyViewModel
{
private AutoResetEvent lock = new AutoResetEvent(true);
private aync Task CriticalRegion()
{
Dosomething();
}
public async Task Button_Click()
{
Debug.WriteLine("Entering Button_Click");
lock.WaitOne();
try
{
await CriticalRegion();
}
finally
{
lock.Set();
Debug.WriteLine("Leaving Button_Click");
}
}
}
I have a button whose click event calls the Button_Click() method
It works normally. But, if I'm quick enough to click the button for another time before the first call to Button_Click() completes, the whole app stops responding.
In the Debug window I find something like this
Entering Button_Click
Entering Button_Click
Looks like the method never completes.
I struggled a bit and find that if I change lock.WaitOne(); to
if (!sync.WaitOne(TimeSpan.FromSeconds(1)))
{
return;
}
In this case my app is able to avoid the deadlock,but I don't know why it works.
I only know about the IPC from my OS course and the async and await pattern in C#, and I'm not so familiar with the thread in .Net world.
I really want to understand what's really going on behind the scenes.
Thanks for any replys ;)
You have a deadlock because WaitOne is blocking the main thread (button click handler is executed on the main thread), while you haven't called ConfigureAwait(false) when calling await, which means that it tries to run the code which is after await on the main thread, even if it's blocked, which would causes a deadlock.
I suggest reading this post for a thorougher explanation of the dead lock situation.
For your code, I would suggest putting the lock deeper, probably within the async Task, and trying to use a more suitable pattern for locking, preferably, the lock statement, because using Event objects is awkward for mutual exclusion, as Hans stated in the comment.
AutoResetEvent.WaitOne() will block infinitely until you call AutoResetEvent.Set(), which you never seem to do except for after the WaitOne() call.
Quoting the AutoResetEvent.WaitOne() documentation:
Blocks the current thread until the current WaitHandle receives a signal.

How can implement awaiting manually?

As an example suppose we have this:
public class MyClass
{
public async Task<bool?> MySynchronousNonBlockingFunction()
{
await here ...
return MyDialogResult;
}
}
and caller must call my function as below:
public async void Button_Click()
{
var instance = new MyClass();
var result = await instance.MySynchronousNonBlockingFunction();
if (result == true)
{
some work ...
}
}
But using Task for awaiting as a such, forces you to make your MySynchronousNonBlockingFunction() function async. And as a side effect you must call MyClass.MySynchronousNonBlockingFunction() only inside an async void to be worked as expected.
I think it is not well for the caller. Because a lazy developer in an application development team may call MySynchronousNonBlockingFunction() without await and then application will not works fine. I want handle this async operation in my code internally and not to the caller. To prevent this development mistakes. same as this one:
public void Button_Click()
{
var instance = new MyClass();
var result = instance.MySynchronousNonBlockingFunction();
if (result == true)
{
some work ...
}
}
In fact, i not want freeze the running thread by wait nor actually pause thread so it must be free to process other its works in another call stack again. Witch i want is actually same as the work of await keyword for a Task execution. is there another option to make this use? and what is your solution here to implement await behavior?
I know there is in c# some ways to lock an object full-fanced and force the execution stack to wait. (for example by using Monitor, or Mutex etc). And all the ways that i found in c# are blocking the running thread.
But, How can i implement awaiting manually? Is there another way to achieve this purpose?
In fact, i want pause ui thread from continue executing at a position, and then resume it again to continue execution in later (from CallStack snapshot position). But i not want freeze or actually pause therad so it must be free to process other its works in another call stack again. Witch i want is actually same as the work of await keyword for a Task execution. is there another option to make this use?
That's not how await works, though. await works by returning and then resuming just that method later. In particular, the call stack is not captured.
If you want to mess around with switching thread stacks, then check out fibers. However, there are no .NET bindings for the fiber APIs, and it's quite possible that a lot of .NET code will simply break if you try to use fibers instead of threads. Then there's the whole question of whether a fiber can actually be an STA context for UI elements; I'm really not sure about that one. In short, here be dragons.
and what is your solution here?
Well, a modal dialog - by definition - is supposed to block other dialogs and run a nested message loop.
If you don't want this behavior, then write modeless dialogs instead. I.e., call Show instead of ShowDialog.
GUI window handlers are message-driven state-machines. You must write code that reflects that. That means no, you cannot sanely just wait, and you should not try.

C# wait until its completed

I have some code, and I have noticed it makes my app freeze. I'm looking for a solution that is better than mine.
How to wait for values which I don't know when I receive and I can't continue until I get them and only solution I figured up was using while until I receive those values.
I'm looking for better solution. The best if it wouldn't freeze my app. It has been told me I should use events, but I couldn't figure out how to do that.
IsBusy = true;
do
{
if (IsBusy)
{
//waiting for values which i don't know when i receive
//i can receive those values in 1sec and also in 2 min
if done -> IsBusy = false;
}
Thread.Sleep(2000);
} while (IsBusy);
IsBusy = true;
do
{
if (IsBusy)
{
//waiting for similar thing until i receive it
if done -> IsBusy = false;
}
Thread.Sleep(5000);
} while (IsBusy);
I think best way to use async await. In C#, asynchronous programming with async await is very easy. Code looks like synchronous.
private async void StartButtonClick(object sender, RoutedEventArgs e)
{
// Starting new task, function stops
// the rest of the function is set to cont
// UI not blocked
Task.Run(async () =>
{
var MyValue = await doSomethingAsync();
}); //there you waiting value
//continue code
}
There may be a couple possibilities, though the description of what you're waiting on is vague enough we may not be able to point you in a specific direction. Some things that might work are:
Event-based coding. If you can change the code of the process you're waiting for, you can have it raise an event that your calling code then handles. This other SO answer has a simple, complete C# program that raises and handles events.
BackgroundWorker often works well in Windows Forms projects, in my experience. In my experience it's one of the simpler ways to get started with multithreading. There's a highly-rated tutorial with code samples here that may help.
There are other ways to multithread your code, too (so that it doesn't "freeze up" while you're waiting), but these may be a simpler starting point for doing what you need.
Async/await may work for you, but I find they're most useful when you already have an existing doSomethingAsync()-type method to work with (such as async web/WCF service methods in a .NET-generated proxy). But if all the code's your own and you're trying to multithread from scratch, they won't be the central mechanism you'd use to get started. (Of course, if it turns out you are waiting on something with a built-in ...Async() method like a web service call, by all means use async/await, and please select #Astemir-Almov's as the accepted answer!)

Turn asynchronous calls into synchronous

Is there any good practice (pattern) in turning asynchronous calls into synchronous?
I have a third party library who's methods are all asynchronos, to get result of almoust any method you must listen to an event, which will bring some context with it.
basically it looks like:
service.BeginSomething(...);
service.OnBeginSomethingCompleted += ;
what I need is to execute some code after BeginSomething when it is really complete (thus after OnBeginSomethingCompleted is triggered). It is very inconvinient to handle the response in the event.
The only way I could think of is running a Thread.Sleep loop and wait till some field on the form is updated, but it doesn't look like very elegant sollution.
I'm using .net 4.0.
You could subclass the main class and provide a synchronous version of the operation. If subclassing is not an option you could create an extension method. Here is how things might look.
public class Subclass : BaseClass
{
public void Something()
{
using (var complete = new ManualResetEventSlim(false))
{
EventHandler handler = (sender, args) => { complete.Set(); };
base.OnBeginSomethingCompleted += handler;
try
{
base.BeginSomething();
complete.Wait();
}
finally
{
base.OnBeginSomethingCompleted -= handler;
}
}
}
}
Update:
One thing I should have pointed out is that this could be problematic in some cases. Consider this example.
var x = new Subclass();
x.BeginSomething();
x.Something();
It should be obvious that the handler in Something could receive the OnBeginSomethingCompleted event from the previous call to BeginSomething. Make sure you guard against this somehow.
Use a ManualResetEvent. In your sync wrapper create it, then pass it to the service.BeginSomething() call as part of the state object. Immediately after the call, WaitOne() on it, this will block.
In the service.OnBeginSomethingCompleted event extract it from the state object and set it, this will unblock the sync caller.
As other said, if possible you should try to make your own code async. If that won't work, does your third-party library support the standard BeginXXX, EndXXX async pattern? If so, then using the TPL would make things easy for you. Your code will look something like this:
using System.Threading.Tasks;
...
var task = Task<TResult>.Factory.FromAsync(
service.BeginSomething, service.EndSomething, arg1, arg2, ..., null);
task.Wait();
var result = task.Result;
The specific overload you'll want to use will depend on how many parameters you need to pass. You can see the list here.
If BeginSomething() returns an IAsyncResult (like a delegate's .BeginInvoke would do), you can get the WaitHandle from that:
service.OnBeginSomethingCompleted += ;
var asyncResult = service.BeginSomething();
asyncResult.AsyncWaitHandle.WaitOne(); // Blocks until process is complete
By the way, by assigning the event handler after starting the async process, you are introducing a race condition where the async call may complete before the event is registered, causing it to never fire.
You might want to look at Reactive Extensions
With Rx you can wrap that into an 'event' basically - the do something like someClass.SomeEvent.Subscribe(d=>...) to subscribe using usually some lambda expression to handle what you need. Also use ObserveOn to handle it on the GUI thread (see the details, this is just a hint).
Other option is to use async await (which is now available for use with VS 2010).
hope this helps
NOTE: Rx have a native support for async methods and turning them into Rx events with pretty much just one call. Take a look at Observable.FromAsyncPattern FromAsyncPattern
The general trend of modern software development (on Windows platform too) is to run, what is possible asynchroniously.
Actually from Windows8 software design guidelines, if the code runs more then 50ms, it has to be asynchronious.
So I would not suggest to block the thread, but instead benefit from that library and provide to the user with some nice looking animation saying "wait, responce comming", or something like this, or some progress bar.
In short, do not block thread, notify a user about what is going on in app and leave it async.
This solution is similar to Brian Gideon's, but I think a little bit cleaner for what you're trying to do. It uses the Monitor object to cause the calling thread to wait until the Completed event is triggered.
public class SomeClass : BaseClass
{
public void ExecuteSomethingAndWaitTillDone()
{
// Set up the handler to signal when we're done
service.OnBeginSomethingCompleted += OnCompleted;
// Invoke the asynchronous method.
service.BeginSomething(...);
// Now wait until the event occurs
lock (_synchRoot)
{
// This waits until Monitor.Pulse is called
Monitor.Wait(_synchRoot);
}
}
// This handler is called when BeginSomething completes
private void OnCompleted(object source, ...)
{
// Signal to the original thread that it can continue
lock (_synchRoot)
{
// This lets execution continue on the original thread
Monitor.Pulse(_synchRoot);
}
}
private readonly Object _synchRoot = new Object();
}

Categories

Resources