This article is a mirror article of machine translation, please click here to jump to the original article.

View: 42759|Reply: 5

[Source] Why is .net/c# Task slower than Thread?

[Copy link]
Posted on 5/3/2017 4:40:28 PM | | | |
.NET 4 includes a new namespace, System.Threading.Tasks, which contains classes that abstract out threading functionality. Use ThreadPool in the background. A task represents the work of a unit that should be completed. The work of this unit can be run in a separate thread or a task can be started synchronously, which requires waiting for the main tuning thread. Using tasks not only gives you an abstraction layer, but also gives you a lot of control over the underlying threads.
Tasks offer a lot of flexibility when it comes to scheduling the work that needs to be done. For example, you can define a continuous task – what work should be done after a task is completed. This can make the difference between a successful task and not. In addition, tasks can be arranged in a hierarchy. For example, a parent task can create a new child task. This creates a dependency so that if you cancel the parent task, its child task will also be canceled.


Nowadays, it is popular to use task execution methods, and it is high-performance, and I don't know where the task performance is.

I tested Task and Thread myself, and I feel that Task is very slow, which greatly affects performance, and the test code is as follows:

We loop through the method 1000 times, and then the method blocks for 100 milliseconds, and the test result is as follows:



Outcome:
Thread execution takes 188 milliseconds
Task execution takes 14,671 milliseconds


The speed difference between the two is 78 times!!!

Task is very slow, don't know why this is happening, is there something wrong with my test code, or what? I hope you can explain why this happens...




Previous:Send messages with ASP.NET Core
Next:C# Parallel Computation Parallel.For&Parallel.For
 Landlord| Posted on 10/13/2020 10:47:17 AM |
tongli1996218 Posted on 2020-10-13 09:34
To ensure the same code as Thread, my operation is the following code, and the above is pseudo-code
PS: Just call await Task.Delay without adding ...

Yes, thanks

Task execution time: 117.0357

You can modify the code as follows:

Task.Run replaces Task.Factory.StartNew because it automatically unpacks internal tasks.
Task.WaitAll waits for an external task instead of an internal one. Using Task.Run does not have nested tasks.


Looking at the msdn documentation, you can see that the Task.Delay Method method creates a task that completes after a specified number of milliseconds. (In fact, a new thread will be created, and await will be added to wait for the task to be executed, I don't know if I understand correctly)

The hyperlink login is visible.

In addition, there is a difference between Task vs void

Task returns an asynchronous method that can wait
The void return asynchronous method can't wait, it does work asynchronously, you can't know when it's done, you can't monitor the status of that async operation.


Reference:

The hyperlink login is visible.
The hyperlink login is visible.

In summary: there is a problem with the code, I should not use Thread.Sleep inside the Task method
Posted on 7/21/2020 1:09:29 PM |
I had the same issue today, using multithreading for AES encryption, Task is much slower than Thread!!
Has the landlord found the reason?
Posted on 10/12/2020 7:24:48 PM |
This post was last edited by tongli1996218 on 2020-10-12 19:43

After testing the owner's code, when the program is started and run multiple times, the time of the task will continue to decrease, and on my computer it will be reduced to less than Thread, and Thread is stable within this time.

It was later found that the Thread.Sleep(100) method had a negative impact on Task, but not on Thread, and Thread.Sleep(100) could be replaced with other time-consuming program verification such as numeric self-addition or await Task.Delay(100).

PS: Thread.Sleep will end the current thread slicing time after calling, such as Thread.Sleep(0) will end the current thread slicing time and transfer it to other threads to run. Inside the task is a thread pool, which can optimize the context switching of threads and reduce CPU loss time (especially for multi-core CPU optimization), while Thread.Sleep(100) will disrupt the switching logic of the original thread pool of the task, causing a lot of CPU time loss

If you replace Thread.Sleep(100) with await Task.Delay(100), you will find that the time consumption of the task is only more than 100 milliseconds, as shown below:
private void TaskTest()
{
        Thread.Sleep(100);
         ... Perform the action
}
Replaced by
private async void TaskTest()
{
      await Task.Delay(100);
      ... Execution takes more than 100 milliseconds for the task, which is the same as the original Thread.Sleep(100) for Thread
}




 Landlord| Posted on 10/12/2020 10:53:05 PM |
tongli1996218 Posted on 2020-10-12 19:24
After testing the owner's code, when the program is started, the time of the task will continue to decrease after running multiple times, and on my computer it will be reduced to less than Thread...

I tried changing it to code like this:
Task.Delay(100000);

Task execution time:14.1306 ms, the total time is indeed very short, however, I found that the method called by Task did not complete the execution.
Posted on 10/13/2020 9:34:33 AM |
This post was last edited by tongli1996218 on 2020-10-13 09:40
Published on 2020-10-12 22:53
I tried changing it to code like this:
Task.Delay(100000);

To ensure the same code as Thread, my operation is the following code, and the above is pseudo-code
PS: Just call await Task.Delay, and then add no code, the thread opened by the task is returned immediately, in order to ensure the simulation of compute-bound, you can use for (int a = 0; a< 1000000; ++a){}; Such methods instead

private async static void TaskTest()
        {
            await Task.Delay(100000);
             Interlocked.Increment(ref run);    lock, but the overhead is smaller
            if(run == j)
             {
                stopwatch. Stop(); Stop monitoring
                TimeSpan timespan = stopwatch. Elapsed;  Gets the total time measured by the current instance
                Console.WriteLine("Task execution time:" + timespan. TotalMilliseconds); Total milliseconds
              }
        The time consumed is also very short


Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com