Contenido del Curso
Advanced C# with .NET
Advanced C# with .NET
1. Introduction to Desktop Development with .NET
Asynchronous Programming vs Threading
In the last chapter, we used Threading to execute a method concurrently in our application. We can do the same using Asynchronous Programming as well:
In the video you saw that we didn't explicitly run the timerLabel.Text = …
statement in the main thread. This will be explained in a bit.
So you might be wondering, what's the difference between Asynchronous Programming and Multi-Threading? Well, it is fundamentally how the two different features work.
If you recall from the previous courses, we had discussed Asynchronous Programming, and we also learnt how to use it in our applications, however, we didn't deeply explore how it exactly worked on a lower level.
In Threading, we manually create new threads to run methods on them for the sake of executing those methods concurrently or parallel to the main thread, and the threads as a whole are dedicated to running those methods. It is also our responsibility to correctly free (delete) the threads and to make sure that there is no conflict between the threads - which we will learn more about in the next chapter.
In Asynchronous Programming, we can run the methods concurrently as well, however, in this case we don't deal with threads manually. So what's happening on the backend? The .NET framework is responsible for assigning and unassigning threads to different tasks when they are executed asynchronously. It is important to note that asynchronous programming does not create new threads, instead, it assigns free threads to different tasks from the Thread Pool.
Thread Pool is a collection of pre-allocated threads that are managed by .NET. These threads are ready and waiting to execute tasks. The thread pool is created automatically by .NET when your application starts up.
So, when the program encounters an asynchronous task, it is assigned to an available thread from the Thread Pool. It is also possible that in certain cases the task is executed over multiple different threads. For example, I/O (input - output) operations, like reading or writing to a file, are performed at a very low level, closer to the CPU, where the concept of threads doesn't exist. So the operations are not bound to any specific thread and hence don't block any specific thread while being performed.
There won't necessarily be a one-to-one mapping from task to threads; therefore, it generally depends upon what kind of operation is being performed. It is completely managed by .NET itself, and we usually don't have to care about the background details. Just like in the video, we didn't explicitly execute the property assignment statement timerLabel.Text = …
in the main thread. .NET automatically decides and assigns relevant threads to relevant parts of the methods.
You can see a brief demonstration in the following video:
So now that we have an idea of how it works on the backend, it is a good time to ask, what is the practical difference between them? And when should we use threading or asynchronous programming?
Asynchronous Programming is based around creating and executing Tasks. While Threading is based around creating and managing Threads.
While similar results can be achieved by using either method, both of those methods are meant for very different things.
Async Programming is useful specifically for I/O bound tasks that need to be performed concurrently without blocking the main program. For-example, while retrieving some data from a file, an API, or a database, the main thread can be blocked, but we can use asynchronous methods to wait for the completion of these tasks concurrently, and retrieve the results of the tasks when the tasks are eventually completed.
Threading on the other hand is more suitable for longer, more expensive operations that are CPU bound. For-example complex lengthy calculations, image or video processing, or simply something like playing a video or audio while keeping the program responsive. We can also assign multiple resource intensive operations to multiple different threads, maximizing the performance.
¿Todo estuvo claro?