Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可数PLINQ产量_C#_Ienumerable_Plinq - Fatal编程技术网

C# 可数PLINQ产量

C# 可数PLINQ产量,c#,ienumerable,plinq,C#,Ienumerable,Plinq,我有一个返回IEnumerable的函数,它通过MAPI迭代收件箱中的对象,但速度相对较慢,因此我将创建一个连接池,并以多线程方式使用它们。是否可以在数千个无用线程中使用PLINQ?如果通过“通过MAPI”引用Outlook对象模型(在VSTO中可用),则不使用线程(无论是通过PLINQ还是显式)。Outlook对象模型将所有调用封送回主线程,这使得该过程比直接从主线程本身运行调用要慢 发件人: 对Outlook对象模型和PIA的所有调用都在Outlook的前台主线程上执行。Outlook对象模

我有一个返回IEnumerable的函数,它通过MAPI迭代收件箱中的对象,但速度相对较慢,因此我将创建一个连接池,并以多线程方式使用它们。是否可以在数千个无用线程中使用PLINQ?

如果通过“通过MAPI”引用Outlook对象模型(在VSTO中可用),则不使用线程(无论是通过PLINQ还是显式)。Outlook对象模型将所有调用封送回主线程,这使得该过程比直接从主线程本身运行调用要慢

发件人:

对Outlook对象模型和PIA的所有调用都在Outlook的前台主线程上执行。Outlook对象模型支持的唯一线程模型是单线程单元(STA)。不支持从后台线程调用Outlook对象模型或PIA,这可能会导致解决方案中出现错误和意外结果


如果要使用托管代码对MAPI进行多线程访问,最好使用库(商业第三方解决方案)。

这是一个针对您的任务的PLINQ解决方案:

public IEnumerable<IMessage> GetMessagesParallel(IEnumerable<IConnection> connections)
{
    return connections
        .AsParallel()
        .WithDegreeOfParallelism(10)
        .SelectMany(connection => GetMessages(connection));
}
public IEnumerable GetMessagesParallel(IEnumerable连接)
{
返回连接
.天冬酰胺()
.平行度(10)
.SelectMany(connection=>GetMessages(connection));
}

此方法接受许多随时可用的连接。10个线程将开始并行地从每个连接中提取消息
GetMessages
是实际提取消息的方法

只要你的线程比可用的内核多,不管它们有多“便宜”,你基本上就是在自讨苦吃。此外,我不确定Windows是否会让一个进程创建数千个线程。嗯,你说的不对,说WMI也太慢了,我只在一个内核上成功地以多线程的方式使用了它,10个内核的加速非常有价值~1000%threads@zneak,如果它是一个CPU限制的计算,那么您是对的。但是对于IO绑定的东西(比如从服务器检索电子邮件),那么使用比核心更多的线程是有意义的。虽然使用异步IO可能更好,这不会浪费线程。@svick,是的,我不这么认为。有1的洞察力。我必须使用自己的(公司的COM),它访问MAPI,用C++编写,并且理解是使用CDO……我不认为CDO也支持线程(但是我不确定)。我没有对它做太多的研究,因为它正逐渐被弃用。嗯,我认为它不支持多线程,我们的COM肯定不支持,但我可以创建许多连接到Exchange的连接器实例。啊,那么你是从Exchange而不是从Outlook阅读的?在这种情况下,我真的帮不了你。事实上,我需要以多线程的方式实现yield,它通过连接器池访问Exchange。顺便说一句,对于MAPI outlook或exchange,我发现它也是IEnumerable.WithDegreeOfParallelism,但在doc中有默认值Math.Min(ProcessorCount,MAX\u SUPPORTED\u DOP)因此,我问了一个问题,.NET是否会将线程限制为可用的内核?@OlegSkripnyak-使用WithDegreeOfParallelism,您可以启动比处理器内核数量更多的线程,这只是默认值。当然有一些上限,但它比默认值高很多。非常感谢!我将尝试实施一些明智的措施