Get thread id and terminate thread - c#

I have an async method that can run multiple times in the same time. This method perform a call to a server so it takes some time to complete. I want each time an instance of this method is called to stop the execution of the same method that run in the same time. I was thinking about creating a list of thread id and everytime the method is called the threads that created for the execution of the older instances of this method will be terminated.
So what i am looking for is a way to get the current thread id that a specific method is running from, and the way to terminate a thread using its id.
PS. I've checked all posts about finding thread id etc but none of these work in UWP.

In UWP you don't have ability to control threads. But you can surely control tasks, and for example, cancel it if needed with with CancellationToken:
CancellationTokenSource tokenSource = new CancellationTokenSource();
await Task.Run(() =>
{
// your job here
}, tokenSource.Token);
// then if you want to cancel the job use tokenSource:
tokenSource.Cancel();
Note that this is only a simple example of using CancellationToken with Task.Run, but most of async methods uses these tokens and even you can convert them to task which will use one.
More about task cancellation you will find at MSDN, Stephen Cleary's blog and more.

Related

Is Async/Await using Task.Run starting a new thread asynchronously?

I have read a lot of articles and still cant get understand this part.
Consider this code :
private async void button1_Click(object sender, EventArgs e)
{
await Dosomething();
}
private async Task<string> Dosomething()
{
await Task.Run((() => "Do Work"));
return "I am done";
}
First question:
When I click the button, it will Call DoSomething and await a Task that creates a Thread from the threadpool by calling Task.Run ( if I am not mistaken ) and all of this runs asynchronously. So I achieved creating a thread that does my work but doing it asynchronously? But consider that I don't need any result back, i just want the work to be done without getting any result back, is there really a need to use async/await , and if so, how?
Second question:
When running a thread asynchronously, how does that work? Is it running on the main UI but on a separate thread or is it running on a separate thread and separate is asynchronously inside that method?
The purpose of creating Async methods is so you can Await them later. Kind of like "I'm going to put this water on to boil, finish prepping the rest of my soup ingredients, and then come back to the pot and wait for the water to finish boiling so I can make dinner." You start the water boiling, which it does asynchronously while you do other things, but eventually you have to stop and wait for it. If what you want is to "fire-and-forget" then Async and Await are not necessary.
Simplest way to do a fire and forget method in C#?
Starting a new task queues that task for execution on a threadpool thread. Threads execute in the context of the process (eg. the executable that runs your application). If this is a web application running under IIS, then that thread is created in the context of the IIS worker process. That thread executes separately from the main execution thread, so it goes off and does its thing regardless of what your main execution thread is doing, and at the same time, your main execution thread moves on with its own work.
1
There's a big difference if you don't await the Task or you await it:
Case you don't await it: DoSomething is called but next sentence is executed while DoSomething Task hasn't been completed.
Case you await it: DoSomething is called and next sentence is executed once DoSomething Task has been completed.
So, the need of async/await will depend on how you want to call DoSomething: if you don't await it is like calling it the fire & forget way.
2
Is it running on the main UI but on a separate thread or is it running
on a seperate thread and separate is asynchronously inside that
method?
Asynchronous code sometimes means other thread (see this Q&A Asynchronous vs Multithreading - Is there a difference?). That is, either if the code is being executed in a separate thread from the UI one or it lets continue the processing of the UI thread while it gets resumed, it's nice because UI loop can still update the screen while other tasks are being done in parallel without freezing the UI.
An asynchronous method (i.e. async method) is a syntactic sugar to tell the compiler that await statements should be treated as a state machine. The C# compiler turns your async/await code into a state machine where code awaiting a Task result is executed after the code that's being awaited.
Interesting Q&As
You might want to review these other Q&As:
Async/Await vs Threads
What's the difference between Task.Start/Wait and Async/Await?
async/await - when to return a Task vs void?
Is Async await keyword equivalent to a ContinueWith lambda?
OP said...
[...] But does this mean that "async/await" will fire off a thread and
Task.Run also fires off a thread or are they both the same thread?
Using async-await doesn't mean "I create a thread". It's just a syntactic sugar to implement continuations in an elegant way. A Task may or may not be a thread. For example, Task.FromResult(true) creates a fake task to be able to implement an async method without requirement it to create a thread:
public Task<bool> SomeAsync()
{
// This way, this method either decides if its code is asynchronous or
// synchronous, but the caller can await it anyway!
return Task.FromResult(true);
}
The type Task<TResult> requires you to return a TResult from your task. If you don't have anything to return, you can use Task instead (which, incidentally, is the base class of Task<TResult>).
But keep in mind that a task is not a thread. A task is a job to be done, while a thread is a worker. As your program runs, jobs and workers become available and unavailable. Behind the scenes, the library will assign your jobs to available workers and, because creating new workers is a costly operation, it will typically prefer to reuse the existing ones, through a thread pool.

async/await. Where is continuation of awaitable part of method performed?

I am really curious how async/await enables your program not to be halted.
I really like the way how Stephen Cleary explains async/await: "I like to think of "await" as an "asynchronous wait". That is to say, the async method pauses until the awaitable is complete(so it waits), but the actual thread is not blocked (so it's asynchornous)."
I've read that async method works synchronously till compilator meets await keywords. Well. If compilator cannot figure out awaitable, then compilator queues the awaitable and yield control to the method that called method AccessTheWebAsync. OK.
Inside the caller (the event handler in this example), the processing pattern continues. The caller might do other work that doesn't depend on the result from AccessTheWebAsync before awaiting that result, or the caller might await immediately. The event handler is waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync. Let's see an msdn example:
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}
Another article from msdn blog says that async/await does not create new thread or use other threads from thread pool. OK.
My questions:
Where does async/await execute awaitable code(in our example downloading a web site) cause control yields to the next row of code of our program and program just asks result of Task<string> getStringTask? We know that no new threads, no thread pool are not used.
Am I right in my silly assumption that CLR just switches the current executable code and awaitable part of the method between each other in scope of one thread? But changing the order of addends does not change the sum and UI might be blocked for some unnoticeable time.
Where does async/await execute awaitable code(in our example downloading a web site) cause control yields to the next row of code of our program and program just asks result of Task getStringTask? We know that no new threads, no thread pool are not used.
If the operation is truly asynchronous, then there's no code to "execute". You can think of it as all being handled via callbacks; the HTTP request is sent (synchronously) and then the HttpClient registers a callback that will complete the Task<string>. When the download completes, the callback is invoked, completing the task. It's a bit more complex than this, but that's the general idea.
I have a blog post that goes into more detail on how asynchronous operations can be threadless.
Am I right in my silly assumption that CLR just switches the current executable code and awaitable part of the method between each other in scope of one thread?
That's a partially true mental model, but it's incomplete. For one thing, when an async method resumes, its (former) call stack is not resumed along with it. So async/await are very different than fibers or co-routines, even though they can be used to accomplish similar things.
Instead of thinking of await as "switch to other code", think of it as "return an incomplete task". If the calling method also calls await, then it also returns an incomplete task, etc. Eventually, you'll either return an incomplete task to a framework (e.g., ASP.NET MVC/WebAPI/SignalR, or a unit test runner); or you'll have an async void method (e.g., UI event handler).
While the operation is in progress, you end up with a "stack" of task objects. Not a real stack, just a dependency tree. Each async method is represented by a task instance, and they're all waiting for that asynchronous operation to complete.
Where is continuation of awaitable part of method performed?
When awaiting a task, await will - by default - resume its async method on a captured context. This context is SynchronizationContext.Current unless it is null, in which case it is TaskScheduler.Current. In practice, this means that an async method running on a UI thread will resume on that UI thread; an async method handling an ASP.NET request will resume handling that same ASP.NET request (possibly on a different thread); and in most other cases the async method will resume on a thread pool thread.
In the example code for your question, GetStringAsync will return an incomplete task. When the download completes, that task will complete. So, when AccessTheWebAsync calls await on that download task, (assuming the download hasn't already finished) it will capture its current context and then return an incomplete task from AccessTheWebAsync.
When the download task completes, the continuation of AccessTheWebAsync will be scheduled to that context (UI thread, ASP.NET request, thread pool, ...), and it will extract the Length of the result while executing in that context. When the AccessTheWebAsync method returns, it sets the result of the task previously returned from AccessTheWebAsync. This in turn will resume the next method, etc.
In general the continuation (the part of your method after await) can run anywhere. In practice it tends to run on the UI thread (e.g. in a Windows application) or on the thread pool (e.g. in an ASP .NET server). It can also run synchronously on the caller thread in some cases ... really it depends on what kind of API you're calling and what synchronization context is being used.
The blog article you linked does not say that continuations are not run on thread pool threads, it merely says that marking a method as async does not magically cause invocations of the method to run on a separate thread or on the thread pool.
That is, they're just trying to tell you that if you have a method void Foo() { Console.WriteLine(); }, changing that to async Task Foo() { Console.WriteLine(); } doesn't suddenly cause an invocation of Foo(); to behave any differently at all – it'll still be executed synchronously.
If by "awaitable code" you mean the actual asynchronous operation, then you need to realize that it "executes" outside of the CPU so there's no thread needed and no code to run.
For example when you download a web page, most of the operation happens when your server sends and receives data from the web server. There's no code to execute while this happens. That's the reason you can "take over" the thread and do other stuff (other CPU operations) before awaiting the Task to get the actual result.
So to your questions:
It "executes" outside of the CPU (so it's not really executed). That could mean the network driver, a remote server, etc. (mostly I/O).
No. Truly asynchronous operations don't need to be executed by the CLR. They are only started and completed in the future.
A simple example is Task.Delay which creates a task that completes after an interval:
var delay = Task.Delay(TimeSpan.FromSeconds(30));
// do stuff
await delay;
Task.Delay internally creates and sets a System.Threading.Timer that will execute a callback after the interval and complete the task. System.Threading.Timer doesn't need a thread, it uses the system clock. So you have "awaitable code" that "executes" for 30 seconds but nothing actually happens in that time. The operation started and will complete 30 seconds in the future.

If an async method is single threaded how can it be run in the background?

I'm trying to understand async/await and have read a number of articles but am still confused about the synchronous/asynchronous nature.
I have the following test console app:
static void Main(string[] args)
{
var test = FooAsync();
Console.WriteLine("After FooAsync");
for (int i = 0; i < 100; i++)
Console.WriteLine("After that");
Console.ReadKey();
}
private static async Task FooAsync()
{
Console.WriteLine("Before delay");
await Task.Delay(1);
Console.WriteLine("After delay");
}
The code gives output along the lines of:
Before delay
After FooAsync
After that
After that
After that
After that
After delay
After that
.
.
I understand that async/await will not create a separate thread for processing and that at the point FooAsync reaches the await Task.Delay(1) line it will return back to Main as the task will not yet have completed, however, as we are only running on a single thread can someone explain what triggers the FooAsync method to resume at some arbitrary point within Main before Main can then continue?
Update
I take it back and i3arnon and dariogriffo are correct. The code does use multiple threads (as I'd have seen before had looked in the debugger or done the obvious as kha suggested). I'd been confused by the Threads section on the following page https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_Threads not realising that a "continuation" actually refers to a continuation task schedule to run as soon as the task being "awaited" finishes.
This isn't single threaded.
When the delay task completes the rest of the method is posted to the ThreadPool and runs concurrently with your main thread. The "trigger" here is the callback of the internal System.Threading.Timer being used inside Task.Delay.
This behaviour depends on the SynchronizationContext. In a UI environment this would have been posted to the same UI thread and would have to wait until that thread is free.
If you would have been waiting for the task returned from FooAsync then you would only have a single thread running each time.
Async/await may create new threads OR NOT, it depends of the nature of the operation.
If the operation is an IO (for example disks/network operations) probably is coded in a way it will not spin a new thread. You can read from here:
The async and await keywords don't cause additional threads to be created?
If you create your own Async operation and you create a thread, that's a different story, that's why you shouldn't do async over sync
http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx
You can check this also but using Thread.CurrentThread to get the Id of the process. (Add that to a Console.WriteLine)
It's a pretty common misconception that the async or await keywords create new threads. They don't.
The threads are created by running a Task. In this case, the thread is created by the Task.Delay call.

Cancel task and wait for it to finish

I have a time consuming task which I need to run in a separate thread to avoid locking the GUI thread. As this task progresses, it updates a specific GUI control.
The catch is that the user might move to another part of the GUI before the task is over, and in that case, I have to:
Cancel the ongoing task (if it is active)
Wait till it's done cancelling: this is crucial, because the time consuming task's objective is to update a specific control. If more than one thread tries to do it at once, things might get messy.
Launch the task from scratch
For a concrete example, imagine the form has two parts: one where you navigate a directory tree, and another where you display thumbnails. When the user navigates to another directory, thumbnails need to be refreshed.
First I thought of using a BackgroundWorker and an AutoResetEvent to wait for cancellation, but I must have messed something because I got deadlocked when cancelling. Then I read about TPL, which is supposed to replace BGW and more primitive mechanisms.
Can this be done easily using TPL?
A few things to note:
You can get a CancellationToken from a CancellationTokenSource
Task cancellation is a cooperative action: if your task does not periodically check the CancellationToken.IsCancellationRequested property, it doesn't matter how many times you try to cancel the task, it will merrily churn away.
Those things said, here's the general idea:
void Main()
{
var tokenSource = new CancellationTokenSource();
var myTask = Task.Factory
.StartNew(() => DoWork(tokenSource.Token), tokenSource.Token);
Thread.Sleep(1000);
// ok, let's cancel it (well, let's "request it be cancelled")
tokenSource.Cancel();
// wait for the task to "finish"
myTask.Wait();
}
public void DoWork(CancellationToken token)
{
while(!token.IsCancellationRequested)
{
// Do useful stuff here
Console.WriteLine("Working!");
Thread.Sleep(100);
}
}

How to stop all tasks when one is finished in c#

I have different tasks to read from different files and find a word into them. I have put them into a task array which I start with waitAny method as following :
foreach (string file in filesList)
{
files[i] = Task.Factory.StartNew(() =>
{
mySearch.Invoke(file);
});
i++;
}
System.Threading.Tasks.Task.WaitAny(files);
I would like to stop all other tasks as soon as one of the tasks finishes (it finishes when it founds the word). For the moment, with waitany, i can know when one tasks finishes, but I don't know how I could know which one has finished and how to stop other tasks.
What would be the best way to achieve this ?
You can use single CancellationToken which all tasks will share. Inside mySearch.Invoke method verify value of token.IsCancellationRequested to cancel task. When some task will be finished cancel others via CancellationTokenSource.Cancel().
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
foreach (string file in filesList)
{
// pass cancellation token to your task
files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token);
i++;
}
Task.WaitAny(files);
tokenSource.Cancel();
BTW you can force token to throw OperationCanceledException when source is canceled by calling token.ThrowIfCancellationRequested()
When creating a Task you can pass a CancelationToken. Set this token when one of the tasks finishes.
This will cause remaining tasks with this token to not execute. Running tasks can receive a OperationCanceledException and stop too.
I highly suggest reading How do I cancel non-cancelable async operations? by Stephen Toub. Essentially what you need to do is cancel all of these tasks, but currently you have no mechanism to cancel them.
The ideal approach would be to create a CancellationTokenSource before the foreach, pass the CancellationToken from that source to each of the child tasks, check that token periodically and stop doing work when you notice it's indicated cancellation. You can then cancel the token source in the WhenAny continuation.
If that's not an option you need to decide if it's important to actually stop the tasks (which, really, just can't be done) or if you just need to continue on with your code without waiting for them to finish (that's easy enough to do).

Categories

Resources