我有一个遗留的第三方COM DLL。我将其注册到注册表中,并在我的.NET/C#控制台应用程序中添加了RCW。注册表显示COM的线程模型为单元(Apartment)。我的整个应用程序的目的是使用多线程并发地向该COM服务器提交多个请求并接收响应。
我正在使用SmartThreadPool来管理线程,在每个线程中,我都会创建新的对象来执行COM查找/请求提交步骤。然而,如果我查看COM服务器日志,仍然可以看到请求按顺序被提交/处理。
问题出在哪里呢?
所以,我认为问题在于COM被配置为单元(Apartment)/STA。
但我的最终目标是让它正常工作,所以我的问题是:
1. 假设我手头只有这个STA COM DLL文件,是否有任何解决办法可以让它并行处理我的请求?
2. 考虑到这样一个事实,当我并行运行两个实例的控制台应用程序时,最终服务器机器上的日志实际上显示两个实例的请求在两个不同的会话中并行处理。因此,最终应用程序已准备好支持并行处理。(我猜这是一个幼稚的问题)假设我能够拿到COM代码,那么将其支持MTA会容易吗?
[这真的太混乱了,我都快疯了!请注意,每个线程都会从COM DLL文件中创建自己的一组新对象,用于COMServer查找、请求、提交等。]
我正在使用SmartThreadPool来管理线程,在每个线程中,我都会创建新的对象来执行COM查找/请求提交步骤。然而,如果我查看COM服务器日志,仍然可以看到请求按顺序被提交/处理。
问题出在哪里呢?
所以,我认为问题在于COM被配置为单元(Apartment)/STA。
但我的最终目标是让它正常工作,所以我的问题是:
1. 假设我手头只有这个STA COM DLL文件,是否有任何解决办法可以让它并行处理我的请求?
2. 考虑到这样一个事实,当我并行运行两个实例的控制台应用程序时,最终服务器机器上的日志实际上显示两个实例的请求在两个不同的会话中并行处理。因此,最终应用程序已准备好支持并行处理。(我猜这是一个幼稚的问题)假设我能够拿到COM代码,那么将其支持MTA会容易吗?
[这真的太混乱了,我都快疯了!请注意,每个线程都会从COM DLL文件中创建自己的一组新对象,用于COMServer查找、请求、提交等。]
应用程序代码
public class start
{
public static void Main(string[] args)
{
StartProcessing();
}
private static void StartProcessing()
{
CoreProcessor pcr = new CoreProcessor();
pcr.start();
}
}
public class CoreProcessor
{
public static ManualResetEvent IsAllDone;
public static int NumberOfActiveThreads;
private SmartThreadPool TPool = new SmartThreadPool();
public void start()
{
IEnumerable<string> LstRequests = FileIO.GetAllRequestFileNames();
NumberOfActiveThreads = LstRequests.Count();
IsAllDone = new ManualResetEvent(false);
foreach(var reqName in LstRequests)
{
ReqInfo req = new ReqInfo(){RequestPath = reqName;};
TPool.QueueWorkItem(new WorkItemCallBack(req.ProcessRequest));
}
if(NumberOfActiveThreads > 0)
IsAllDone.WaitOne();
}
}
public class ReqInfo
{
public string RequestPath;
public void ProcessRequest()
{
ABC_COM_Request req = new ABC_COM_XMLUTIL().CreateRequest();
ABC_COM_Server svr = new ABC_COM_ServerLookup().lookup("serverhostname", 1099);
ABC_COM_Response resp = svr.submit(req);
if (InterLocked.Decrement(ref CoreProcessor.NumberOfActiveThreads) == 0)
CoreProcessor.IsAllDone.Set();
}
}