2016-03-30 17 views
3

En iyi çözümü bulmak için yardımınıza ihtiyacım var. Bu benim orjinal kodum:Ne zaman görev sayısı

Çizgilerle bir dosya okuyacak ve her satırı bir göre işleyecektir. Ancak, dosyada 1 milyondan fazla satır varsa, görev dizisi daha büyük, bu kod hala iyi mi? ya da başka bir çözüm bulmalıyım. Lütfen bana yardım et. Teşekkürler.

+4

[CodeReview] (http://codereview.stackexchange.com) –

+0

'a ait olduğu için bu sorunun konu dışı olarak kapatılmasına oy veriyorum TPL bir iç tanıtıcıyı dahili olarak kullanıyor, bu yüzden bir milyon iş parçacığı başlatmamalı. Görevlerin performansının nasıl davrandığından emin değilsiniz. Sadece 8'den başlayarak (çekirdek sayısı) ve bu 8 görev arasındaki çizgileri bölmek performansı artırabilir. – Domysee

+0

@YuvalItzchakov Kod incelemesi değil.Sorunu anlamak için kod vermek birçok kelimeyi yazmaktan daha iyidir. İhtiyacım olan şey, problemimi çözmek için yardımın. Teşekkürler. –

cevap

4

Bu kötü bir fikir. Bu çok fazla iş parçacığı başlatır. Bunu yapmak için

bir çok daha iyi bir yolu basitçe şöyle Parallel.ForEach() kullanmaktır: Bu ancak, zaman uyumsuz/bekliyoruz kullanmaz

using System; 
using System.IO; 
using System.Threading.Tasks; 

namespace Demo 
{ 
    static class Program 
    { 
     static void Main() 
     { 
      string filename = @"Your test filename goes here"; 
      Parallel.ForEach(File.ReadLines(filename), process); 
     } 

     private static void process(string line) 
     { 
      Console.WriteLine(line); 
     } 
    } 
} 

. Ancak, isterseniz tüm görevi bir görevde Parallel.ForEach()'a sarabilirsiniz. Eğer Task Parallel Library (Microsoft Nuget paketi) kullanmak istiyorsanız

Alternatif olarak, böyle bir şey yapabilirsiniz:

using System; 
using System.IO; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Threading.Tasks.Dataflow; 

namespace Demo 
{ 
    static class Program 
    { 
     static void Main() 
     { 
      Task.Run(test).Wait(); 
     } 

     static async Task test() 
     { 
      string filename = @"Your filename goes here"; 
      await processFile(filename); 
     } 

     static async Task processFile(string filename) 
     { 
      var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 8, BoundedCapacity = 100 }; 
      var action = new ActionBlock<string>(s => process(s), options); 

      foreach (var line in File.ReadLines(filename)) 
       await action.SendAsync(line); 

      action.Complete(); 

      await action.Completion; 
     } 

     static void process(string line) 
     { 
      Thread.Sleep(100); // Simulate work. 
      Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + line); 
     } 
    } 
} 

Bu size async destek verir.


Ek: threadpool kısma bir gösteri.

(Bu Shay __ 'nın yorumlara yanıt olarak budur.)

Görev ya da öylesine bir saniyeden kısa çalıştırmak için uzun sürer uzun süren görevler bir sürü sen Boğarak threadpool görebilirsiniz başlayın.

Geçerli işlemin iş parçacığı iş parçacığı sayısı ThreadPool.GetMinThreads(out workers, out ports); numaralı aramaya döndürülen worker sayımına eşitse veya bu değeri aşarsa bu olur.

Böyle bir durumda, yeni bir threadpool iş parçacığı oluşturulmadan önce yeni bir threadpool iş parçacığının başlatılması kısa bir süre (sistemimde bir saniye) geciktirilir. Çoğu zaman bu, başka bir iş parçacığı iş parçacığının kullanılabilir hale gelmesine izin vermiş olacak ve bunun yerine kullanılacaktır (bu, 'un kısaltması için önemli bir nedendir).

Aşağıdaki kodu sorunu gösterir: İlk 8 konu çok çabuk başlamak ama sonra yeni ipler throttled nasıl

Min workers = 8 
Thread 3 started at time 00:00:00.0098651 
Thread 6 started at time 00:00:00.0098651 
Thread 8 started at time 00:00:00.0099841 
Thread 5 started at time 00:00:00.0099680 
Thread 7 started at time 00:00:00.0099918 
Thread 4 started at time 00:00:00.0098739 
Thread 10 started at time 00:00:00.0100828 
Thread 9 started at time 00:00:00.0101833 
Thread 11 started at time 00:00:01.0096247 
Thread 12 started at time 00:00:02.0098105 
Thread 13 started at time 00:00:03.0099824 
Thread 14 started at time 00:00:04.0100671 
Thread 15 started at time 00:00:05.0098035 
Thread 16 started at time 00:00:06.0099449 
Thread 17 started at time 00:00:07.0096293 
Thread 18 started at time 00:00:08.0106774 
Thread 19 started at time 00:00:09.0098193 
Thread 20 started at time 00:00:10.0104156 
Thread 3 started at time 00:00:10.0109315 
Thread 8 started at time 00:00:10.0112171 
Thread 7 started at time 00:00:10.0112531 
Thread 9 started at time 00:00:10.0117256 
Thread 4 started at time 00:00:10.0117920 
Thread 10 started at time 00:00:10.0117298 
Thread 6 started at time 00:00:10.0109381 
Thread 5 started at time 00:00:10.0112276 
Thread 21 started at time 00:00:11.0095859 
Thread 11 started at time 00:00:11.0101189 
Thread 22 started at time 00:00:12.0095421 
Thread 12 started at time 00:00:12.0111173 
Thread 23 started at time 00:00:13.0095932 ... 

Not: Benim sistemde

int workers, ports; 
ThreadPool.GetMinThreads(out workers, out ports); 
Console.WriteLine("Min workers = " + workers); // Prints 8 on my system. 
var sw = Stopwatch.StartNew(); 

for (int i = 0; i < 100; ++i) 
{ 
    Task.Run(() => 
    { 
     Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} started at time {sw.Elapsed}"); 
     Thread.Sleep(10000); 
    }); 
} 

Console.ReadLine(); 

, bu şu yazdırır Saniyelerin ilk partisi sona erene kadar ve daha sonra yeniden kullanılabilir olana kadar, saniyede bir civarına kadar. Ayrıca, bu etkinin yalnızca iş parçacıklarının sonlandırmak için göreceli olarak uzun bir süre alması durumunda gerçekleştiğine dikkat edin. Üste |

+0

Güzel. Çok teşekkürler. –

+1

"Bu çok fazla iş parçacığı başlatır" - Bunun doğru olduğundan emin değilim. Detaylandırır mısınız? –

+0

@shay__ Dosyadaki her satır için 'Task.Run()' işlevini çağırırsanız, satır başına bir iş parçacığı başlatmayı dener. Birkaç iş parçacığından sonra, iş parçacığı başına yarım saniyelik bir gecikme başlatmaya başlayacaktır, bu basit bir test için çok sayıda iş parçacığı oluşturmasını engelleyecektir, çünkü önceki iş parçacıkları yeni olanların oluşturulmasından ve yeniden kullanılmasından önce çıkmış olacaktır. Ancak, her satırın işlenmesi yeterince yavaşsa, iş parçacıklarının sayısı artmaya devam edecektir. –

İlgili konular