it-swarm-tr.com

Görev ve iş parçacığı arasındaki fark nedir?

C # 4.0'da System.Threading.Tasks ad alanında Task var. Thread ve Task arasındaki gerçek fark nedir? Kendi kendime öğrenmek için bazı örnek programlar (MSDN'den alınan yardım) yaptım.

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

ancak fikir o kadar açık olmadığı için birçok şüpheniz var.

Ben başlangıçta benzer bir soru türü için Stackoverflow içinde aradım ama bu soru başlığı ile aynı olabilirdi olabilir olabilir. Buraya daha önce burada sorulmakta olan aynı soru hakkında bir şey bilen varsa, lütfen bağlantı referansını veriniz.

355
user372724

Görev yapmak istediğiniz bir şeydir.

Bir iş parçacığı, bu görevi gerçekleştiren birçok olası işçiden biridir.

.NET 4.0 açısından, bir Görev zaman uyumsuz bir işlemi temsil eder. İplik (ler), işi parçalara ayırarak ve ayrı dişlere atayarak bu işlemi tamamlamak için kullanılır.

295
Mitch Wheat

Bilgisayar bilimi terimlerinde, Task, bir gelecek veya bir söz şeklindedir. (Bazı insanlar bu iki terimi eşanlamlı olarak kullanır, bazıları ise farklı şekilde kullanır, hiç kimse bir kesin tanımını kabul edemez.) Temel olarak, bir Task<T> "size bir T döndürür, ama doğru değil" şimdi tatlım, biraz meşgulüm, neden daha sonra gelmiyorsun?

Thread bu vaadi yerine getirmenin bir yoludur. Ancak her Task yepyeni bir Thread gerektirmez. (Aslında, bir iş parçacığı oluşturmak genellikle istenmeyen bir durumdur, çünkü bunu yapmak, iş parçacığı havuzundaki mevcut bir iş parçacığını yeniden kullanmaktan çok daha pahalıdır. Bir andan daha fazlası.) Beklediğiniz değer dosya sisteminden geliyorsa ya da bir veritabanı veya ağ, o zaman bir iş parçacığının oturmasına ve başka isteklere hizmet verebilmesi için verileri beklemesine gerek yoktur. Bunun yerine, Task, hazır olduklarında değerleri almak için bir geri çağrı kaydedebilir.

Özellikle, Task, değil say neden değerinin döndürülmesi bu kadar uzun zaman alır. Bu olabilir hesaplanması çok zaman alıyor ya da alması uzun zaman alıyor olabilir. Yalnızca eski durumda, Thread komutunu çalıştırmak için Task kullanırsınız. (.NET'te, iş parçacıkları çok pahalı, bu nedenle genellikle bunlardan olabildiğince kaçınmak istersiniz ve yalnızca birden çok CPU'da birden fazla ağır hesaplama yapmak istiyorsanız bunları kullanmak isteyebilirsiniz. Örneğin, Windows'ta bir iş parçacığı 12 KiByte ağırlığındadır (örneğin Sanırım) Linux'ta bir iş parçacığı 4 KiByte kadar ağır, Erlang/BEAM'de sadece 400 Byte bile. .NET'te 1 MiByte!)

431
Jörg W Mittag

Thread

Çıplak metal şey, muhtemelen kullanmanız gerekmiyor, muhtemelen LongRunning görevini kullanabilir ve .NET Framework 4'te (Şubat 2002) bulunan TPL - Task Parallel Library'den faydalanabilirsiniz. yukarıda (ayrıca .NET Çekirdeği).

Görevler

Konular üzerinde soyutlama. Bu thread pool özelliğini kullanır (görevi LongRunning işlemi olarak belirtmezseniz, öyleyse, sizin için kaputun altında yeni bir iş parçacığı oluşturulur).

İplik Havuzu

Adından da anlaşılacağı gibi: bir iş parçacığı havuzu. .NET framework sizin için sınırlı sayıda iş parçacığı işliyor. Neden? Çünkü işlemcide sadece 8 çekirdekli pahalı CPU işlemlerini gerçekleştirmek için 100 iş parçacığı açmak kesinlikle iyi bir fikir değildir. Çerçeve bu havuzu sizin için koruyacak, dişlileri yeniden kullanacak (her operasyonda onları yaratacak/öldürmeyecek) ve bazılarını CPU'nuzun yanmayacağı şekilde paralel olarak çalıştıracaktır.

Tamam, ama her birini ne zaman kullanmalı?

Devam etmek: her zaman görevleri kullanın.

Görev bir soyutlamadır, bu yüzden kullanımı çok daha kolaydır. Her zaman görevleri kullanmayı denemenizi ve bir ipliği kendiniz halletmenizi gerektiren bir sorunla karşı karşıya kalmanızı (muhtemelen zamanın% 1'i) öneririm.

ANCAK farkında olun:

  • G/Ç Bağımlı: G/Ç bağlanmış işlemler için (veritabanı çağrıları, okuma/yazma dosyaları, API çağrıları vb.) Normal görevleri kullanmaktan kaçının, LongRunning görevlerini kullanın ( veya gerekirse ) konuları. Çünkü görevleri kullanmak sizi bir kaç iş parçacığıyla meşgul bir havuza yönlendirir ve sıranın havuza girmesini bekleyen başka bir çok görev yapar.
  • CPU Bound: CPU'ya bağlı işlemler için sadece normal görevleri kullanın (dahili olarak thread havuzunu kullanır) ve mutlu olun.
31
fabriciorissetto

Ne yapmak istediğinizi belirtmek için Task kullanabilirsiniz, ardından Task ile Thread ekleyin. bu yüzden Task, GUI iş parçacığı yerine yeni yapılan Thread içinde çalıştırılacaktı.

TaskFactory.StartNew(Action action) ile Task kullanın. Burada bir temsilci yürütüyorsunuz, böylece herhangi bir iş parçacığı kullanmazsanız, aynı iş parçacığında (GUI iş parçacığı) yürütülür. Eğer bir konudan bahsederseniz, bu Task i farklı bir dizide çalıştırabilirsiniz. Bu gereksiz bir iştir, çünkü doğrudan temsilciyi çalıştırabilir veya bu temsilciyi bir iş parçacığına ekleyebilir ve bu dizgiyi bu iş parçacığında uygulayabilirsiniz. Bu yüzden kullanmayın. bu sadece gereksiz. Yazılımınızı optimize etmek istiyorsanız bu, kaldırılması iyi bir adaydır.

** Lütfen Action'in bir delegate olduğunu unutmayın.

7
Gryphes

Yukarıdaki noktalara ek olarak, şunu bilmek güzel olurdu:

  1. Bir görev varsayılan olarak bir arka plan görevidir. Ön plan göreviniz olamaz. Öte yandan, bir iş parçacığı arka plan veya ön plan olabilir (davranışı değiştirmek için IsBackground özelliğini kullanın).
  2. İş parçacığı havuzunda oluşturulan görevler, kaynakların korunmasına yardımcı olan iş parçacıklarını geri dönüştürür. Bu yüzden çoğu durumda görevler varsayılan seçiminiz olmalıdır.
  3. İşlemler hızlıysa, iş parçacığı yerine bir görev kullanmak daha iyidir. Uzun süren işlemler için, görevler dişlilere göre fazla avantaj sağlamaz.
6
user2492339

Kullanıcı arabirimini dondurmamak için Winforms ve basit bir arka plan çalışanı ile etkileşimde bulunmak için genellikle Task kullanıyorum. Task kullanmayı tercih ettiğimde burada bir örnek

private async void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    await Task.Run(() => {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
    })
    buttonDownload.Enabled = true;
}

VS

private void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    Thread t = new Thread(() =>
    {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
        this.Invoke((MethodInvoker)delegate()
        {
            buttonDownload.Enabled = true;
        });
    });
    t.IsBackground = true;
    t.Start();
}

aradaki fark, MethodInvoker ve daha kısa kod kullanmanıza gerek olmamasıdır.

4
ewwink

Görev yapmak istediğiniz bir işlem gibidir, Thread bu işlemi çoklu işlem düğümleri aracılığıyla yönetmenize yardımcı olur. Threading karmaşık bir kod yönetimine yol açabildiğinden görev, hafif bir seçenektir
Her zaman MSDN'den (dünyanın en iyisi) okumayı önereceğim

Görev

Kon

2
Saurabh