是否Parallel.ForEach块? [英] Does Parallel.ForEach Block?

查看:199
本文介绍了是否Parallel.ForEach块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请问.NET函数 Parallel.ForEach 阻塞调用线程?我的猜测是对的行为是其中之一:

  1. 是的,它阻止,直到最慢的项目执行的回报。
  2. 不,这不会阻止,并立即返回控制。以平行模式运作中的项目在后台线程完成。

或许别的东西正在发生的事情,任何人都知道肯定?

在一个日志类实现这个当这个问题上来:

 公共类MultipleLoggingService:LoggingServiceBase
{
    私人只读表< LoggingServiceBase> loggingServices;

    公共MultipleLoggingService(名单< LoggingServiceBase> loggingServices)
    {
        this.loggingServices = loggingServices;
        LogLevelChanged + = OnLogLevelChanged;
    }

    私人无效OnLogLevelChanged(对象发件人,LogLevelChangedArgs参数)
    {
        loggingServices.ForEach(升=> l.LogLevel = LogLevel的);
    }

    公众覆盖LogMessageResponse的LogMessage(LogMessageRequest要求)
    {
        如果(request.LogMessage)
            Parallel.ForEach(loggingServices,L => l.LogMessage(要求));

        返回新LogMessageResponse {MessageLogged = request.LogMessage};
    }
}
 

注意的LogMessage 方法调用其他一些日志服务。我需要的那部分立即返回,所以它不会阻塞调用线程。


更新:基于从别人的意见(我们已经证实的行为是#1)。所以,我已经建议使用任务库,并改写了环像这样的:

 如果(request.LogMessage)
            的foreach(在loggingServices VAR loggingService)
                Task.Factory.StartNew(()=> loggingService.LogMessage(要求));
 

解决方案

1号是正确的; Parallel.ForEach 不返回,直到循环完成。如果你不希望这样的行为,你可以简单地执行你的循环为工作,并在另一个线程中运行它。

Does the .net function Parallel.ForEach block the calling thread? My guess as to the behavior is one of these:

  1. Yes, it blocks until the slowest item executing returns.
  2. No, it doesn't block and returns control immediately. The items to run in parallel are done on background threads.

Or perhaps something else is happening, anyone know for sure?

This question came up when implementing this in a logging class:

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};
    }
}

Notice the LogMessage method calls some other logging services. I need that part to return immediately, so it doesn't block the calling thread.


Update: Based on comments from others (we have confirmed the behavior is #1). So I have taken advice to use the Task library and rewritten the loop like this:

          if (request.LogMessage)
            foreach (var loggingService in loggingServices)
                Task.Factory.StartNew(() => loggingService.LogMessage(request));

解决方案

Number 1 is correct; Parallel.ForEach does not return until the loop has completed. If you don't want that behavior, you can simply execute your loop as a Task and run it on another thread.

这篇关于是否Parallel.ForEach块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆