Câu hỏi hay. Trong ví dụ của bạn, mức độ song song là khá thấp ngay cả trên một bộ xử lý lõi tứ, nhưng với một số chờ đợi mức độ song song có thể nhận được khá cao.
// Max concurrency: 5
[Test]
public void Memory_Operations()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
monitor.Add(monitor.Count);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
Bây giờ hãy xem điều gì sẽ xảy ra khi hoạt động chờ được thêm vào để mô phỏng yêu cầu HTTP.
// Max concurrency: 34
[Test]
public void Waiting_Operations()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(1000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
Tôi chưa thực hiện bất kỳ thay đổi nào và mức độ đồng thời/song song đã tăng đáng kể. Đồng thời có thể tăng giới hạn của nó với ParallelOptions.MaxDegreeOfParallelism
.
// Max concurrency: 43
[Test]
public void Test()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(1000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
// Max concurrency: 391
[Test]
public void Test()
{
ConcurrentBag<int> monitor = new ConcurrentBag<int>();
ConcurrentBag<int> monitorOut = new ConcurrentBag<int>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(monitor.Count);
System.Threading.Thread.Sleep(100000);
monitor.TryTake(out int result);
monitorOut.Add(result);
});
Console.WriteLine("Max concurrency: " + monitorOut.OrderByDescending(x => x).First());
}
tôi reccommend thiết ParallelOptions.MaxDegreeOfParallelism
. Nó sẽ không nhất thiết phải tăng số lượng các chủ đề được sử dụng, nhưng nó sẽ đảm bảo bạn chỉ bắt đầu một số sane của chủ đề, mà có vẻ là mối quan tâm của bạn.
Cuối cùng để trả lời câu hỏi của bạn, không có bạn sẽ không nhận được tất cả các chủ đề để bắt đầu cùng một lúc. Sử dụng Parallel.Invoke nếu bạn đang tìm kiếm để gọi song song hoàn hảo ví dụ: điều kiện cuộc đua thử nghiệm.
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623363344
// 636462943623368346
// 636462943623368346
// 636462943623373351
// 636462943623393364
// 636462943623393364
[Test]
public void Test()
{
ConcurrentBag<string> monitor = new ConcurrentBag<string>();
ConcurrentBag<string> monitorOut = new ConcurrentBag<string>();
var arrayStrings = new string[1000];
var options = new ParallelOptions {MaxDegreeOfParallelism = int.MaxValue};
Parallel.ForEach<string>(arrayStrings, options, someString =>
{
monitor.Add(DateTime.UtcNow.Ticks.ToString());
monitor.TryTake(out string result);
monitorOut.Add(result);
});
var startTimes = monitorOut.OrderBy(x => x.ToString()).ToList();
Console.WriteLine(string.Join(Environment.NewLine, startTimes.Take(10)));
}
Tôi đã sử dụng Parallel.ForEach (FilePathArray, path => ... để đọc khoảng 24.000 tệp tối nay tạo một tệp mới cho mỗi tệp mà tôi đọc. Mã đơn giản. để áp đảo các đĩa 7200 RPM tôi đã đọc từ lúc sử dụng 100 %.Trong khoảng thời gian một vài giờ tôi đã xem thư viện song song spin off hơn 8.000 chủ đề.Tôi đã thử nghiệm bằng cách sử dụng MaxDegreeOfParallelism và chắc chắn đủ 8000+ chủ đề biến mất.Tôi đã thử nghiệm nó nhiều lần bây giờ với kết quả tương tự –
Nó * có thể * bắt đầu 1000 chủ đề cho một số 'DoSomething' thoái hóa. (Như trong trường hợp tôi hiện đang xử lý vấn đề trong mã sản xuất không đặt giới hạn và sinh ra 200+ chủ đề do đó popping hồ bơi kết nối SQL .. Tôi khuyên bạn nên thiết lập Max DOP cho bất kỳ công việc mà không thể được trivially lý do về như là ràng buộc CPU rõ ràng.) – user2864740