Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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/3/gwt/3.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# 并行和COM(Outlook MAPI)数据采集和发布?_C#_Com_Task Parallel Library_Exchange Server_Mapi - Fatal编程技术网

C# 并行和COM(Outlook MAPI)数据采集和发布?

C# 并行和COM(Outlook MAPI)数据采集和发布?,c#,com,task-parallel-library,exchange-server,mapi,C#,Com,Task Parallel Library,Exchange Server,Mapi,我已经检查了一些答案,但我仍然不确定并行获取和发布COM对象的正确方法是什么 我特别使用了一个Parallel.ForEach来提高性能,在它里面,它调用了MS.Outlook(2010 ExchangeServer)。然而,通过释放COM对象,我偶尔会得到ComException 使用Parallel库处理COM对象的正确方法是什么 System.Threading.Tasks.Parallel.ForEach(myList, myItem => { String freeBu

我已经检查了一些答案,但我仍然不确定并行获取和发布COM对象的正确方法是什么

我特别使用了一个
Parallel.ForEach
来提高性能,在它里面,它调用了MS.Outlook(2010 ExchangeServer)。然而,通过释放COM对象,我偶尔会得到ComException

使用
Parallel
库处理COM对象的正确方法是什么

System.Threading.Tasks.Parallel.ForEach(myList, myItem =>
{
     String freeBusySlots = "";
     Outlook.Recipient myReceipient = null;

     try
     {
         myReceipient = namespaceMAPI.CreateRecipient(myItem.ToString());
     }
     catch (Exception ex)
     {
         ...
     }
     finally
     {
        if (myReceipient == null)
        {
            ...
        }

        Marshal.ReleaseComObject(myReceipient ); // -> I get an exception here sometimes ... how to avoid this
        myReceipient = null;
     }
}); // Parllel.forEach

一般来说,您不应该使用
ReleaseComObject
。相反,只需等待RCW对象被收集,然后让GC为您完成工作。正确使用此API非常困难

此外,很可能所有Outlook COM对象都位于STA中。如果是这样的话,那么对它们进行并行操作将毫无益处。从后台线程发出的每个调用都将简单地返回到前台线程进行处理。因此,背景线程将不会增加任何价值,只是混淆


我不是100%确定这些是STA对象,但如果不是,我会非常惊讶

无法从辅助线程使用Outlook对象模型。有时它是有效的,但它往往在最不合适的时候爆炸

从Outlook 2013起,如果从辅助线程访问OOM对象,Outlook将立即引发错误

如果您的代码是从另一个应用程序运行的,请记住,所有调用都将序列化到Outlook主线程,因此使用多个线程没有任何意义


还请注意,扩展MAPI(仅限C++或Delphi)或Redemption(包装扩展MAPI并可从任何语言访问)可以从多个线程中使用,但您的里程数会因特定MAPI提供程序而异(IMAP4存储提供程序是最差的)。

ReleaseComObject完全可以。@DmitryStreblechenko否,这是一个非常危险的API,在这种特殊情况下,它是完美的。该变量在本地级别上声明,从不从外部引用它,Outlook对象模型是用非托管C++编写的,而不是.NET。如果您处理大量Outlook项目,这实际上是使其工作的唯一方法-Exchange server限制同时打开的对象的数量,如果您超过此限制,它将拒绝再打开任何对象。@JaredPar:10x用于回答。因此,并行访问Outlok Exchange服务器不会带来任何好处。确实没有可能的方法来加速来自我的outlook加载项的exchange server调用?只要不接触outlook对象模型,就可以在COM加载项中使用辅助线程,这意味着只使用C++/Delphi或类似于包装器的Redemption(RDO对象族)。我的代码将从outlook加载项运行。其思想是并行化到exchange服务器的连接,以减少其负载。你知道如何用赎回来制作上述代码吗?如何找到特定的MAPI提供程序?是否适合从
MAPI
切换到
EWS
?我主要使用方法
getFreeBusy
来联系ExchangeServer。当然,EWS是纯HTTP的,您可以在辅助线程中这样做。