Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.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服务器的多个实例_C#_.net_Com_Interop - Fatal编程技术网

C# 并行连接到同一COM服务器的多个实例

C# 并行连接到同一COM服务器的多个实例,c#,.net,com,interop,C#,.net,Com,Interop,我已经编写了一个C#程序,可以与COM服务器对话进行模拟。它工作起来没有任何问题,但是COM服务器执行的模拟相当占用处理器,并且只运行单核 因此,我曾经在多个线程之间分配工作负载。然而,COM服务器生成的所有模拟结果似乎都在其类的所有实例中共享,因此当我仅使用1个线程运行并行任务时,一切正常,但当我使用多个线程运行任务时,结果完全混乱(由于多个线程有效地导致模拟引擎在读取结果时用新结果替换其结果) 我想知道是否有一种方法可以多次连接到COM服务器以停止类实例的结果共享 编辑 我连接到COM服务器

我已经编写了一个C#程序,可以与COM服务器对话进行模拟。它工作起来没有任何问题,但是COM服务器执行的模拟相当占用处理器,并且只运行单核

因此,我曾经在多个线程之间分配工作负载。然而,COM服务器生成的所有模拟结果似乎都在其类的所有实例中共享,因此当我仅使用1个线程运行并行任务时,一切正常,但当我使用多个线程运行任务时,结果完全混乱(由于多个线程有效地导致模拟引擎在读取结果时用新结果替换其结果)

我想知道是否有一种方法可以多次连接到COM服务器以停止类实例的结果共享

编辑

我连接到COM服务器的过程是:

  • 使用Project->Add References->COM(VS2010)添加引用
  • 使用以下代码实例化模拟器对象:

    dss = new OpenDSSengine.DSS();
    dss.Start(0);
    
上述代码在的本地线程数据初始化器(localInit)参数中调用,因此为每个线程创建一个新的
dss
对象,但获得的结果似乎在所有线程中都是通用的


COM服务器是一个dll。

当您指定COM服务器实际上是一个进程内服务器(一个.dll而不是.exe)时,这意味着每次执行
new DSS()
时,您实际上创建了一个新实例(除非它是使用单例类工厂创建的,这是罕见但可能的)

根据您的描述,问题似乎在于
DSS
实现使用了一些静态/全局状态,这会在并行执行时导致数据混乱

在这种情况下,您可以使用在单独的进程中运行服务器的每个实例。如果默认代理项(dllhost.exe)不够用,。请注意,将服务器移动到另一个进程将为针对服务器执行的每个方法调用引入封送处理开销

还请注意,如果您使用的是,您的并行化将没有任何效果,因为对服务器的所有调用都是由COM基础结构序列化的


话虽如此,在开始之前,请确保问题不在调用方,即并行化而不是服务器本身。

当您指定COM服务器实际上是一个进程内服务器(一个.dll而不是.exe)时,这意味着每次执行
new DSS()
时,实际上都创建了一个新实例(除非它是使用单例类工厂创建的,这很少见,但也是可能的)

根据您的描述,问题似乎在于
DSS
实现使用了一些静态/全局状态,这会在并行执行时导致数据混乱

在这种情况下,您可以使用在单独的进程中运行服务器的每个实例。如果默认代理项(dllhost.exe)不够用,。请注意,将服务器移动到另一个进程将为针对服务器执行的每个方法调用引入封送处理开销

还请注意,如果您使用的是,您的并行化将没有任何效果,因为对服务器的所有调用都是由COM基础结构序列化的


话虽如此,在开始之前,请确保问题不在调用方,即并行化而不是服务器本身。

首先尝试创建COM对象的多个实例(只需多次调用new OpenDSEngine.DSS(),将结果存储在单独的变量或数组中)。如果COM服务器实现良好,那么这些多个实例将在您的流程中共存,而不会相互干扰,并且您的多线程客户端代码可以同时使用它们


如果您仍然发现这些实例相互干扰,这意味着COM服务器正在使用某个进程全局的状态。唯一的解决方法是按照其他人的建议,通过多个代理进程调用多个COM对象。

首先尝试创建COM对象的多个实例t(只需多次调用新的OpenDSSENGE.DSS(),将结果存储在单独的变量或数组中)。如果COM服务器实现良好,那么这些多个实例将在流程中共存,而不会相互干扰,并且多线程客户端代码可以同时使用它们


如果您仍然发现这些实例相互干扰,这意味着COM服务器正在使用某个进程全局的状态。唯一的解决方法是通过多个代理进程调用多个COM对象,正如其他人所建议的那样。

显然,您的COM服务器不是线程安全的。您已经知道了当您多次使用new时,获取多个实例,但仍然不具有线程安全性是很常见的。例如,这些实例可能共享全局变量。没有神奇的公式可以解决此问题,在其自己的进程中运行每个实例并与之对话(例如WCF)。这可能会很痛苦。您确定这是一个多线程COM服务器吗e第一位(即不在STA中运行)?是什么阻止您创建COM服务器的多个实例(COM服务器是一个对象,而不是一个进程)?它是进程外服务器(.exe)还是进程内(dll)?您如何获得COM对象?它可能是单例COM服务器(例如,通过使用DECLARE_CLASSFACTORY_singleton)。请提供更多信息。谢谢,在上面添加了相应的注释。@ZdeslavVojkovic,创建COM服务器的多个实例的想法听起来似乎可行,但我还没有找到使用上面列出的方法来实现这一点的方法。如何做到这一点?您的COM服务器是exe(我假设是)还是