已与其底层RCW分离的COM对象不能与TPL和跨线程COM对象一起使用



我在Wpf中有一个主类,所以它在MTA中,我必须处理需要在STA中的COM对象。

所以我有下面的代码来创建一个对象的实例。

COMObject localCOMObject;
Thread thread = new Thread(() =>
{
try { localCOMObject = new COMObject(); }
finally { DidFinish= 1; }
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

我还有一个列表对象,它引用了这个对象(WorkingObjects)

List<WorkingObject> WorkingObjects= new List<WorkingObject>();
WorkingObject.Add(new WorkingObject(localCOMObject));
...

在我的代码中,我运行

await Task.Run(() => 
{
Parallel.ForEach(WorkingObjects, WorkingObject=>
{
WorkingObject.Execute();
});
});

在我的Execute方法中,我使用我的COMObject对象,这是我得到异常的时候:

COM对象已与其底层RCW分离,无法使用。

当我的代码是:时,它会工作

await Task.Run(() => 
{
COMObject localCOMObject = new COMObject();
Parallel.ForEach(WorkingObjects, WorkingObject=>
{
WorkingObject=localCOMObject ;
WorkingObject.Execute();
});
});

但现在我需要在我的任务之外做一些事情。

我在Wpf中有一个主类,所以它在MTA(…)中

你确定吗?Windows窗体和WPF专门用于在STA中运行。

(…)和我必须处理一个需要在STA中的COM对象。

COM对象的寿命不能超过其单元。STA的寿命不能超过其线程。

您正在创建一个STA线程,然后创建一个COM对象,最后这个线程退出。如果该对象已注册为居住在STA中,那么您的对象现在处于未定义状态,并且完全不可靠。

当我的代码是:时,它就可以工作了

await Task.Run(() => 

(…)

这是因为对象是在MTA单元中创建的(线程池线程使用MTA),或者是在使用对象时处于活动状态的STA中创建的。

如果对象是在ThreadingModel设置为Both或Free的情况下注册的,则它在MTA中。如果该对象设置为"单个",则它将在使用该对象之前未被销毁的主机STA中创建。

相关内容

最新更新