Chức năng .net Parallel.ForEach có chặn chặn cuộc gọi không? Tôi đoán hành vi này là một trong những hành vi sau:Không Parallel.ForEach Block?
- Có, nó chặn cho đến khi mục chậm nhất thực hiện trả về.
- Không, nó không chặn và trả về kiểm soát ngay lập tức. Các mục để chạy song song được thực hiện trên các chủ đề nền.
Hoặc có thể có điều gì khác đang xảy ra, bất kỳ ai cũng biết chắc chắn?
Câu hỏi này đã đưa ra khi thực hiện điều này trong một lớp học khai thác gỗ:
public class MultipleLoggingService : LoggingServiceBase
{
private readonly List<LoggingServiceBase> loggingServices;
public MultipleLoggingService(List<LoggingServiceBase> loggingServices)
{
this.loggingServices = loggingServices;
LogLevelChanged += OnLogLevelChanged;
}
private void OnLogLevelChanged(object sender, LogLevelChangedArgs args)
{
loggingServices.ForEach(l => l.LogLevel = LogLevel);
}
public override LogMessageResponse LogMessage(LogMessageRequest request)
{
if (request.LogMessage)
Parallel.ForEach(loggingServices, l => l.LogMessage(request));
return new LogMessageResponse{MessageLogged = request.LogMessage};
}
}
Chú ý phương pháp LogMessage
gọi một số dịch vụ khai thác gỗ khác. Tôi cần phần đó để trả về ngay lập tức, vì vậy nó không chặn chuỗi gọi.
Cập nhật: Dựa trên nhận xét của người khác (chúng tôi đã xác nhận hành vi là # 1). Vì vậy, tôi đã đưa ra lời khuyên để sử dụng thư viện Task và viết lại vòng lặp như sau:
if (request.LogMessage)
foreach (var loggingService in loggingServices)
Task.Factory.StartNew(() => loggingService.LogMessage(request));
Thanks for the tip! Bạn có xảy ra một đoạn mã nhỏ về cách sử dụng 'Tác vụ' trong ngữ cảnh này không? Cảm ơn, Paul –
@PaulFryer: 'Task t = Task.TaskFactory.StartNew (() => {/ * Parallel.For vào đây * /});' – Richard
Về mặt kỹ thuật, chuỗi gọi được sử dụng trong vòng lặp song song. Vì vậy, nó không phải là "lãng phí" chỉ cần chặn trên vòng lặp - nó được sử dụng như một trong các chủ đề công nhân. –