Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 42759|Jawab: 5

[Sumber] Mengapa Tugas .net/c# lebih lambat daripada Thread?

[Salin tautan]
Diposting pada 03/05/2017 16.40.28 | | | |
.NET 4 menyertakan namespace baru, System.Threading.Tasks, yang berisi kelas yang mengabstraksi fungsionalitas threading. Gunakan ThreadPool di latar belakang. Tugas mewakili pekerjaan unit yang harus diselesaikan. Pekerjaan unit ini dapat dijalankan dalam utas terpisah atau tugas dapat dimulai secara sinkron, yang membutuhkan menunggu utas penyetelan utama. Menggunakan tugas tidak hanya memberi Anda lapisan abstraksi, tetapi juga memberi Anda banyak kendali atas utas yang mendasarinya.
Tugas menawarkan banyak fleksibilitas dalam hal menjadwalkan pekerjaan yang perlu dilakukan. Misalnya, Anda dapat menentukan tugas berkelanjutan – pekerjaan apa yang harus dilakukan setelah tugas selesai. Ini dapat membuat perbedaan antara tugas yang berhasil dan tidak. Selain itu, tugas dapat diatur dalam hierarki. Misalnya, tugas induk dapat membuat tugas turunan baru. Ini menciptakan dependensi sehingga jika Anda membatalkan tugas induk, tugas turunannya juga akan dibatalkan.


Saat ini, sangat populer untuk menggunakan metode eksekusi tugas, dan berkinerja tinggi, dan saya tidak tahu di mana kinerja tugasnya.

Saya menguji Task dan Thread sendiri, dan saya merasa bahwa Task sangat lambat, yang sangat memengaruhi kinerja, dan kode pengujiannya adalah sebagai berikut:

Kami mengulang metode 1000 kali, dan kemudian metode diblokir selama 100 milidetik, dan hasil pengujiannya adalah sebagai berikut:



Hasil:
Eksekusi utas membutuhkan waktu 188 milidetik
Eksekusi tugas membutuhkan waktu 14.671 milidetik


Perbedaan kecepatan antara keduanya adalah 78 kali!!

Tugasnya sangat lambat, tidak tahu mengapa ini terjadi, apakah ada yang salah dengan kode pengujian saya, atau apa? Saya harap Anda dapat menjelaskan mengapa ini terjadi...




Mantan:Mengirim pesan dengan ASP.NET Core
Depan:C# Komputasi Paralel Paralel.For&Parallel.For
 Tuan tanah| Diposting pada 13/10/2020 10.47.17 |
tongli1996218 Dipaparkan pada 2020-10-13 09:34
Untuk memastikan kode yang sama dengan Thread, operasi saya adalah kode berikut, dan di atas adalah kode semu
PS: Panggil saja tunggu Task.Delay tanpa menambahkan ...

Ya, terima kasih

Waktu eksekusi tugas: 117.0357

Anda dapat memodifikasi kode sebagai berikut:

Task.Run menggantikan Task.Factory.StartNew karena secara otomatis membongkar tugas internal.
Task.WaitAll menunggu tugas eksternal, bukan tugas internal. Menggunakan Task.Run tidak memiliki tugas berlapis.


Melihat dokumentasi msdn, Anda dapat melihat bahwa metode Task.Delay Method membuat tugas yang selesai setelah jumlah milidetik tertentu. (Bahkan, utas baru akan dibuat, dan await akan ditambahkan untuk menunggu tugas dieksekusi, saya tidak tahu apakah saya mengerti dengan benar)

Login hyperlink terlihat.

Selain itu, ada perbedaan antara Tugas vs void

Tugas mengembalikan metode asinkron yang dapat menunggu
Metode asinkron pengembalian void tidak dapat menunggu, itu bekerja secara asinkron, Anda tidak dapat mengetahui kapan selesai, Anda tidak dapat memantau status operasi asinkron itu.


Referensi:

Login hyperlink terlihat.
Login hyperlink terlihat.

Singkatnya: ada masalah dengan kode, saya tidak boleh menggunakan Thread.Sleep di dalam metode Task
Diposting pada 21/07/2020 13.09.29 |
Saya mengalami masalah yang sama hari ini, menggunakan multithreading untuk enkripsi AES, Tugas jauh lebih lambat daripada Thread!!
Apakah tuan tanah telah menemukan alasannya?
Diposting pada 12/10/2020 19.24.48 |
Posting ini terakhir diedit oleh tongli1996218 pada 2020-10-12 19:43

Setelah menguji kode pemilik, ketika program dimulai dan dijalankan beberapa kali, waktu tugas akan terus berkurang, dan di komputer saya akan berkurang menjadi kurang dari Thread, dan Thread stabil dalam waktu ini.

Kemudian ditemukan bahwa metode Thread.Sleep(100) memiliki dampak negatif pada Task, tetapi tidak pada Thread, dan Thread.Sleep(100) dapat diganti dengan verifikasi program lain yang memakan waktu seperti penambahan mandiri numerik atau tunggu Task.Delay(100).

PS: Thread.Sleep akan mengakhiri waktu pemotongan utas saat ini setelah memanggil, seperti Thread.Sleep(0) akan mengakhiri waktu pemotongan utas saat ini dan mentransfernya ke utas lain untuk dijalankan. Di dalam tugas terdapat kumpulan utas, yang dapat mengoptimalkan peralihan konteks utas dan mengurangi waktu kehilangan CPU (terutama untuk pengoptimalan CPU multi-core), sedangkan Thread.Sleep(100) akan mengganggu logika pengalihan kumpulan utas asli tugas, menyebabkan banyak kehilangan waktu CPU

Jika Anda mengganti Thread.Sleep(100) dengan await Task.Delay(100), Anda akan menemukan bahwa konsumsi waktu tugas hanya lebih dari 100 milidetik, seperti yang ditunjukkan di bawah ini:
pribadi void TaskTest()
{
        Benang.Tidur(100);
         ... Lakukan tindakan
}
Digantikan oleh
privat asinkron void TaskTest()
{
      tunggu Task.Delay(100);
      ... Eksekusi membutuhkan waktu lebih dari 100 milidetik untuk tugas, yang sama dengan Thread.Sleep(100) asli untuk Thread
}




 Tuan tanah| Diposting pada 12/10/2020 22.53.05 |
tongli1996218 Dipaparkan pada 2020-10-12 19:24
Setelah menguji kode pemilik, ketika program dimulai, waktu tugas akan terus berkurang setelah berjalan beberapa kali, dan di komputer saya akan berkurang menjadi kurang dari Thread...

Saya mencoba mengubahnya menjadi kode seperti ini:
Tugas.Penundaan(100000);

Waktu eksekusi tugas:14.1306 ms, total waktunya memang sangat singkat, namun, saya menemukan bahwa metode yang disebut oleh Tugas tidak menyelesaikan eksekusi.
Diposting pada 13/10/2020 09.34.33 |
Posting ini terakhir diedit oleh tongli1996218 pada 2020-10-13 09:40
Diterbitkan pada 2020-10-12 22:53
Saya mencoba mengubahnya menjadi kode seperti ini:
Tugas.Penundaan (100000);

Untuk memastikan kode yang sama dengan Thread, operasi saya adalah kode berikut, dan di atas adalah kode semu
PS: Cukup panggil await Task.Delay, lalu tambahkan tidak ada kode, utas yang dibuka oleh tugas segera dikembalikan, untuk memastikan simulasi compute-bound, Anda dapat menggunakan for (int a = 0; sebuah< 1000000; ++a){}; Metode seperti itu sebagai gantinya

void statis asinkron pribadi TaskTest()
        {
            tunggu Task.Delay(100000);
             Interlocked.Increment(ref run);    kunci, tetapi overhead lebih kecil
            jika(jalankan == j)
             {
                stopwatch. Berhenti(); Berhenti memantau
                Rentang waktu rentang waktu = stopwatch. Berlalu;  Mendapatkan total waktu yang diukur oleh instance saat ini
                Console.WriteLine("Waktu eksekusi tugas:" + rentang waktu. TotalMilidetik); Total milidetik
              }
        Waktu yang dikonsumsi juga sangat singkat


Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com