Difference between Task and Thread
It's a frequent, deep question that you can't escape being asked wherever you go, and it's well known that Tasks are based on Threads. But the connection between Task and Thread is so simple and pure that I didn't expect it. It only takes a few dozen lines of code to show how it works.A simple simulation example illustrating Task and its scheduling problem, this is a really good article.
The task system consists of two classes.Task
as well asTaskScheduler
。
Task stores delegate methods that need to be executed in multiple threads, and despite the layers of encapsulation, the delegate is eventually called internally. But the execution method of the task is not open to the programmer, it is given to the TaskScheduler, and the only thing exposed to the programmer is theGive the task to the task scheduler this method.. Tasks are frankly built around the center of the delegate. As for the thread on which the delegate is executed, the responsibility is not there and is given to the task scheduler.
The TaskScheduler is used to determine which thread to put the Task on for execution, the simplest of which is thenew Thread
Put the Task and its internal delegates into a new thread for execution. The more complex one is to call the queuing method of the thread pool, put the Task into the queue of pending Tasks to be accessed by the thread pool, let the queue keep popping up Tasks, and then put them into a certain thread to be executed.
Implement two TaskSchedulers
I'll give you two task schedulers to illustrate how simple this is. One scheduler is used to create a thread for each task to execute, and the other scheduler is used to create a thread pool and fetch the task for execution with threads from the thread pool.
- Always use a new thread for tasks
//Execute the task using a new thread
public class ThreadScheduler:TaskScheduler
{
protected override void QueueTask(Task task)
{
//What I didn't realize is that it's just a straight upTaskput intoThreadIt's been executed in the
new Thread(()=>TryExecuteTask(task))
.Start();
}
}
//test (machinery etc)
ThreadScheduler threadScheduler = new ThreadScheduler();
(() => ($"Task1 is excuted in thread {}"), default, , threadScheduler);
(() => ($"Task2 is excuted in thread {}"), default, , threadScheduler);
(() => ($"Task3 is excuted in thread {}"), default, , threadScheduler);
(() => ($"Task4 is excuted in thread {}"), default, , threadScheduler);
- Creating and executing tasks using a thread pool
//Executing Tasks with Thread Pools
public class ThreadPoolScheduler:TaskScheduler
{
private BlockingCollection<Task> tasks=new();
private Thread[] threads;
//Creating a thread pool,Let the thread keep going to the queue to take out the task to be executed
public ThreadPoolScheduler(int threadNum)
{
threads=new Thread[threadNum];
for(int i=0;i<threadNum;i++)
{
threads[i]=new Thread(InvokeNext);
threads[i].Start();
}
void InvokeNext()
{
while(true)
{
var task=();
if(task!=null)
{
TryExecuteTask(task);
}
}
}
}
//New mission joining the team
protected override void QueueTask(Task task)
{
(task);
}
}
As you can see from these two schedulers, the only thing that is clear about the action of starting a task is that theGive the task to the schedulerInstead, the task is executed immediately. Whether or not the task is immediately put into a thread for execution depends on the implementation of the task scheduler. For example, in the first type of scheduler, the task is executed immediately; in the second type of scheduler, the task may wait until an idle thread takes it out of the queue.
pull back (of a key (in music)
Another difference between tasks and multithreading is that having callbacksContinueWith
. This eliminates the need to use blocking or thread synchronization to solve this very common problem of doing one thing after another.Dainai Lao AThe proposed way to do this is to open a new task inside the task, in the same function that executes the delegate, to execute the next delegate after the execution of the previous delegate is complete.
Since this trigger node is near the end of the previous thread, it enables a callback.
Since the two methods, callback and start task, have the same return type Task, chained calls are again implemented.
synchronous
Asynchronous is explained asAsynchronous programming in a synchronous manner
. This is a further improvement on tasks. This stuff can only be implemented through syntactic sugar, and what it achieves is to transform the callback execution model of a task into what intuitively looks like a sequential execution model. On the subject of multithreaded synchronization, one can derive such a chain of evolution.
Thread | Task | async/await |
---|---|---|
Thread synchronization with locks, semaphores, etc. | pull back (of a key (in music) | Programming in a synchronized manner |
What is the difference between asynchronous and multithreading? The main difference lies in the way threads are synchronized, I guess.