I would like to find out why the following needs to be blocked in order to get the console to write:
Task.Factory.StartNew(() => Console.WriteLine("KO"), TaskCreationOptions.LongRunning);
and this does not:
new Thread(() => Console.WriteLine("KO")).Start();
According to C# 5.0 in a nutshell, TaskCreationOptions.LongRunning is supposed to make the task NOT use pooled threads (which are background threads), meaning it should be using a foreground thread just like a regular thread, except with a regular thread, one does not need to Console.Readline or Wait() but with a Task, doesn't matter whether it's long running or not, I always have to block the main thread in some way.
So what good is LongRunning or OnComplete() or GetAwaiter() or GetResult() or any other function which is supposed to render a result If I always have to block the main thread myself to actually get the result?
You're relying on undefined behaviour. Don't do that.
You don't need to wait for a task to have it work - it's just the only way to be sure that it actually completed in some way. I assume you're just using a console application with nothing but the code above - by the time the thread actually gets to the Console.WriteLine part, the main thread is dead, and with it all the background threads. new Thread creates a foreground thread by default, which prevents the application as a whole from exiting, despite the fact that the "main" thread was terminated.
The idea behind tasks (and any kind of asynchronous operations, really) is that they allow you to make concurrent requests, and build chains of asynchronous operations (making them behave synchronously, which you usually want). But you still need points of synchronization to actually make a workable application - if your application exits before the tasks are done, too bad :)
You can see this if you just do a Console.ReadLine instead of waiting for the task to finish explicitly - it still runs in the background, independently of the main thread of execution, but now you give it enough time to complete. In most applications, you do asynchronous operations asynchronously to the main thread - for example, a result of a button click might be an asynchronous HTTP request that doesn't block the UI, but if the UI is closed, the request is still terminated.
Related
I know the differences between a thread and a task., but I cannot understand if creating threads inside tasks is the same as creating only threads.
It depends on how you use the multithreaded capabilities and the asynchronous programming semantics of the language.
Simple facts first. Assume you have an initial, simple, single-threaded, and near empty application (that just reads a line of input with Console.ReadLine for simplicity sake). If you create a new Thread, then you've created it from within another thread, the main thread. Therefore, creating a thread from within a thread is a perfectly valid operation, and the starting point of any multithreaded application.
Now, a Task is not a thread per se, but it gets executed in one when you do Task.Run which is selected from a .NET managed thread pool. As such, if you create a new thread from within a task, you're essentially creating a thread from within a thread (same as above, no harm done). The caveat here is, that you don't have control of the thread or its lifetime, that is, you can't kill it, suspend it, resume it, etc., because you don't have a handle to that thread. If you want some unit of work done, and you don't care which thread does it, just that's it not the current one, then Task.Run is basically the way to go. With that said, you can always start a new thread from within a task, actually, you can even start a task from within a task, and here is some official documentation on unwrapping nested tasks.
Also, you can await inside a task, and create a new thread inside an async method if you want. However, the usability pattern for async and await is that you use them for I/O bound operations, these are operations that require little CPU time but can take long because they need to wait for something, such as network requests, and disk access. For responsive UI implementations, this technique is often used to prevent blocking of the UI by another operation.
As for being pointless or not, it's a use case scenario. I've faced situations where that could have been the solution, but found that redesigning my program logic so that if I need to use a thread from within a task, then what I do is to have two tasks instead of one task plus the inner thread, gave me a cleaner, and more readable code structure, but that it's just personal flair.
As a final note, here are some links to official documentation and another post regarding multithreaded programming in C#:
Async in Depth
Task based asynchronous programming
Chaining Tasks using Continuation Tasks
Start multiple async Tasks and process them as they complete
Should one use Task.Run within another Task
It depends how you use tasks and what your reason is for wanting another thread.
Task.Run
If you use Task.Run, the work will "run on the ThreadPool". It will be done on a different thread than the one you call it from. This is useful in a desktop application where you have a long-running processor-intensive operation that you just need to get off the UI thread.
The difference is that you don't have a handle to the thread, so you can't control that thread in any way (suspend, resume, kill, reuse, etc.). Essentially, you use Task.Run when you don't care which thread the work happens on, as long as it's not the current one.
So if you use Task.Run to start a task, there's nothing stopping you from starting a new thread within, if you know why you're doing it. You could pass the thread handle between tasks if you specifically want to reuse it for a specific purpose.
Async methods
Methods that use async and await are used for operations that use very little processing time, but have I/O operations - operations that require waiting. For example, network requests, read/writing local storage, etc. Using async and await means that the thread is free to do other things while you wait for a response. The benefits depend on the type of application:
Desktop app: The UI thread will be free to respond to user input while you wait for a response. I'm sure you've seen some programs that totally freeze while waiting for a response from something. This is what asynchronous programming helps you avoid.
Web app: The current thread will be freed up to do any other work required. This can include serving other incoming requests. The result is that your application can handle a bigger load than it could if you didn't use async and await.
There is nothing stopping you from starting a thread inside an async method too. You might want to move some processor-intensive work to another thread. But in that case you could use Task.Run too. So it all depends on why you want another thread.
It would be pointless in most cases of everyday programming.
There are situations where you would create threads.
Reading these two articles, SynchronisationContext and Async/Await. I'm very familiar with the way the ASP.NET SynchronisationContext handles the re-entry of async method execution back onto the request thread.
One of the big issues with re-entry is that if you use .Wait() or .Result you can cause a deadlock, why:
When the await completes, it attempts to execute the remainder of the async method within the captured context. But that context already has a thread in it, which is (synchronously) waiting for the async method to complete.
You get this because of the single thread that is being used by the SynchronisationContext and the way it permits only one chunk of code to run at a time.
What would be the implications of using Task.Factory.StartNew and assigning it a ThreadPool SynchronisationContext within an ASP.NET application?
I'm not bothered by why you would do this, rather more what would happen?
I know you are never supposed to Fire-and-Forget an async operation in ASP.NET because the thread may be cleared up before the async operation has completed. Would this also be true in the case of a ThreadPool SynchronisationContext.
What would be the implications of using Task.Factory.StartNew and assigning it a ThreadPool SynchronisationContext within an ASP.NET application?
There's no reason to use StartNew; Task.Run is superior in almost every use case. Also, you don't need to "assign" a thread pool SynchronizationContext, because thread pool threads have that naturally.
So, sure, you could do this:
await Task.Run(async () => { ... });
and all of your ... code will run on a thread pool thread (outside the request context), and resume on a thread pool thread (outside the request context).
This usage also doesn't have the problem of fire-and-forget, because our code is awaiting the result.
But I generally discourage this on ASP.NET, because think about what it's doing:
The code queues work (...) to the thread pool.
Then it asynchronously waits for that work to complete. During this time, the original request thread is returned to the thread pool.
When the work completes, the calling method continues in the request context.
So it causes an extra thread switch while giving you no benefit. It's possible to have a small amount of parallelism, but then you're talking about some potentially serious scalability limitations. Every time I've done parallelism on ASP.NET in production, I've ended up ripping it out.
I know you are never supposed to Fire-and-Forget an async operation in ASP.NET because the thread may be cleared up before the async operation has completed. Would this also be true in the case of a ThreadPool SynchronisationContext.
Actually, it's not because of a particular thread getting aborted. It's because the entire AppDomain is torn down. This includes aborting all threads.
So, yes, on ASP.NET, fire-and-forget using the thread pool is just as bad as any other kind of fire-and-forget:
Task.Run(() => ...); // bad!
At the very least, you should register the work with the ASP.NET runtime (which does not make the work reliable in the true sense of the word - it only minimizes the chance that the work will be aborted). Modern ASP.NET has HostingEnvironment.QueueBackgroundWorkItem for this.
Before ASP.NET added this method, I had a library that registered the work in a very similar way. I used Task.Run on purpose to run the registered work outside any request context and with a thread pool SynchronizationContext.
I need to make sure some of my code runs in the background and doesn't stop block the UI thread, and I thought I knew how to use Task.Factory.New, but as I read more and more, it seems that it doesn't always create a new thread but sometimes runs it on the UI thread if the thread pool thinks that's the way to go so now I am pretty confused over what to use to be safe that the method is not blocking the UI thread. I should also add that I don't need a return value from the method , I just need it to run asynchronously ( in the background ).
So what's the difference between these methods below and what is best to use to make sure it doesn't block the UI thread ?
And is it really true that Task.Factory.StartNew doesn't always create a thread that runs in the background and doesn't block the UI?
public Form1()
{
Task.Factory.StartNew(() => Thread.Sleep(1000));
Task.Run(() => Thread.Sleep(1000));
Task<int> longRunningTask = LongRunningOperationAsync();
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000);
return 1;
}
I should also add that I don't need a return value from the method
Beware of a common problem: just because you don't need a return value doesn't mean you shouldn't await the returned task. awaiting the task provides you with exception information as well. The only time it's appropriate to ignore the returned task is when you don't care about the return value and you don't care about any exceptions the background work may raise (that is, you're OK with silently swallowing them).
In easily >99% of cases, the appropriate behavior is to await the task.
So what's the difference between these methods below
StartNew is an outdated way to run code on a thread pool thread. You should use Run instead of StartNew. I describe why in painful detail on my blog, but the short answer is that StartNew does not understand async delegates and has inappropriate default options.
async is completely different. Run executes code on a thread pool thread, but async rewrites the code so that it doesn't need a thread while there's an asynchronous operation in progress. So, the Run example will block a thread pool thread for 1000ms in the Thread.Sleep call. The async example will run on the UI thread and then not use the UI thread for 1000ms in the await Task.Delay call.
and what is best to use to make sure it doesn't block the UI thread?
Both Task.Run and async are appropriate in UI apps, depending on the nature of the background code.
If your code is asynchronous (usually all I/O-bound code), then you should use async/await. Note that imposing asynchrony "top-down" is hard. Don't think about "forcing code off the UI thread"; instead, identify the naturally-asynchronous parts of your system (DB, file, WebAPI calls, etc), change them to be async at the lowest level, and work up from there.
If your code is synchronous (CPU-bound), then you can use Task.Run if it takes too long to run on your UI thread.
And is it really true that Task.Factory.StartNew doesn't always create a thread that runs in the background and doesn't block the UI?
Run always executes code on threads from the thread pool. The rules for StartNew are much more complex, but in your example example code, if TaskScheduler.Current == TaskScheduler.Default, then StartNew will also use a thread from the thread pool.
The two examples you give are pretty much the same and depend of the context you are using them on.
Tasks are a way to describe a packet of work with meta information to know about its state, synchronize multiple tasks, cancel them etc. The main idea about tasks and asynchronicity is that you don't have to care about "where" (on which thread) this unit of work is executed, it is performed asynchronously, that's all you need to know. So no worries for your UI-Thread, as long as you are working asynchronously, it won't be locked (that's one of the main improvements since Win8 and the async/await keywords, every UI Manipulation has to be async not to bloat the UI).
As for async&await, those are in fact syntactic sugar. In many simple cases, you don't need to care about the task itself, you just want the asynchronous computation "do this and give me the answer when you have it".
int x = await ComputeXAsync(); //Returns a Task<int> which will be automatically unwrapped as an int
If you need to synchronize tasks, for example start multiple tasks in parallel and wait that all of them are done before continuing, you can't rely on the simple await Task<int> format, you then need to work with the task itself, its Status property and in this case the Task.WaitAll(task[]) API.
Edit: I really recommend the chapter of JonSkeets Book C# in Depth (last edition). The Async/Await part is really well explained and will take you way further than any reading online will do.
The first two are actually the same. see here
Well you can think of it as a task is something you want to be done.
A thread is something like a worker which does the task for you. So basically a threads helps you doing a task, but it doesn't return a value.
a task does not create its own OS thread. Instead, tasks are executed by a TaskScheduler; the default scheduler simply runs on the ThreadPool.
See Here
An example is. A remote request you can do as task, you want the job done but dont know when it will be. But a TCPListener for the server I would run as a thread, because it always needs to listen to the socket.
Like Andreas Niedermair pointed out, you can also use longliving tasks with the TaskCreationOptions
I'm trying to get a grasp on asynchronous programming in C#/.NET. I read an article (link) on Brown University's website for the cs168 course that defines asynchronous programming as interleaving tasks within the same thread. It says, "Now we can introduce the asynchronous model... In this model, the tasks are interleaved with one another, but in a single thread of control", and shows interleaving very clearly in a figure. But I can't seem to get two tasks to interleave within the same thread in .NET. Is there a way to do that?
I wrote some simple apps to try to test this theory, but I'm not sure if I'm doing it correctly. The main program outputs to the screen every so often, using Thread.Sleep() to simulate work. The asynchronous task does the same. If multiple threads are used, the output is interleaved. But I'm trying to test on a single thread.
I have a WPF app that runs everything on the UI thread, but the task and main program always output sequentially. I create and start the task like this:
var taskFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
var task = taskFactory.StartNew(workDelegate);
I have a console app that starts the task delegate using Task.Run(workDelegate);, but that runs them on different thread pool threads. I'm not sure how to make them both run on the same thread. If I try the same approach I used in WPF I get a runtime InvalidOperationException, "The current SynchronizationContext may not be used as a TaskScheduler".
Multiple tasks won't automatically be interleaved on a single thread. To do that, you have to specify the points in task code where the thread is allowed to cut over to another task. You can do this via a mechanism like await Task.Yield. If you're running on a single thread, the thread will not be able to allow other work to progress unless it explicitly yields.
When you use your TaskScheduler to start every task, the message pump in WPF schedules each task to run on the UI thread, and they will run sequentially.
I have a console app that starts the task delegate using Task.Run(workDelegate);, but that runs them on different thread pool threads. I'm not sure how to make them both run on the same thread.
You would need to install a custom SynchronizationContext into a thread which allowed you to post work to that thread.
You cannot run two concurrent Tasks in the same thread-pool thread. Each thread-pool thread can run one Task at a time. If you want to do two things in one thread, your options what I see now:
1. Combine the two things into one Task
2. Create two tasks and one would depend on the other one. SO in the end they would run sequentially after each other. By default it's not guaranteed that they would run in the same thread though, but you should not rely on that anyway.
It's not clear to me what you want to do. According to the books the UI and the thread of your WPF should do any heavy lifting number crunching work. It should take care of the UI and organize the worker threads/tasks. You would start operations in the background using async.
what happens if i put a System.Threading.Thread.Sleep() into a Task that is started with TaskFactory.StartNew()?
Does it put the executing Thread itself to sleep or will this Thread execute another Task while the first one Sleeps?
I`m asking this because I´m currently working on a Server which must sometimes wait to receive data from its clients, and if I put the Task asleep, which is handling the client-connection, I would like to know if the Thread that executes this specific Task is then able to Handle another connection while the first one waits for data.
Thread.Sleep always make the currently executed thread sleep, whether that thread is executing a task or not.
There's no concept of a task sleeping - only a thread. Of course the thread pool will allow multiple threads to execute, so you'll probably just end up with more threads than you really need.
It sounds like you may want to wait for the data asynchronously, continuing with the rest of the work for the task when that data is available.
C# 5's async methods will make all of this a lot simpler.