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 |
[CodeReview] (http://codereview.stackexchange.com) –
'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
@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. –