WPF线程:“已经与其底层RCW分离的COM对象不能被使用”。 [英] WPF Thread: "COM object that has been separated from its underlying RCW cannot be used."

查看:1424
本文介绍了WPF线程:“已经与其底层RCW分离的COM对象不能被使用”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到以下错误:

 无法使用已从其底层RCW分离的COM对象。 

我相信问题是因为COM对象被调用不是在它创建的线程上 - STA。我试图实现IDisposable,但它没有为我工作。



有几个帖子处理类似的问题,但仍然不能解决我的问题:



从终结器调用RCW是否安全?
发布Excel对象在我的析构函数中



任何人都可以发布一个示例/解释如何从另一个线程正确访问COM对象?



这里是显示问题的最小代码:

  using System; 
using System.Threading;

命名空间Test.ComInterop
{
public class Program
{
MyCom _myCom;

[STAThread]
static void Main(string [] args)
{
new Program();
}

public Program()
{
_myCom = new MyCom();

//这个方法调用works
string version = _myCom.ComMethod();

StartThread();
}

private void StartThread()
{
Thread t = new Thread(UIRun);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}

void UIRun()
{
TestUI window = new TestUI();
window.Show();

//此方法调用失败
window.Title = _myCom.ComMethod();

window.Closed + =(sender2,e2)
=> window.Dispatcher.InvokeShutdown();

System.Windows.Threading.Dispatcher.Run();
}
}

class MyCom
{
private dynamic _com;
public MyCom()
{
_com = Activator.CreateInstance(
Type.GetTypeFromProgID(Excel.Application));
}

public string ComMethod()
{
return(string)_com.Version;
}
}
}


解决方案>

问题是你的程序的启动线程。它创建COM对象,启动一个线程,然后退出。作为清除主线程的一部分,.NET调用CoUninitialize(),这是COM对象的结束。得到这个错误是预期的结果。



只是没有点让你的主启动线程退出。让它做你现在做的工作,你自己的线程,问题解决。


I am getting following error:

"COM object that has been separated from its underlying RCW cannot be used."

I am sure the problem is because COM object is being called not on the thread it has been created - STA. I tried to implement IDisposable but it has not worked for me.

There is a couple of posts dealing with similar problem but which still do not solve my issue:

Is it safe to call an RCW from a finalizer? Release Excel Object In My Destructor

Could anyone post an example/explain how COM object should be correctly accessed from another thread?

Here is minimal code which shows the problem:

using System;
using System.Threading;

namespace Test.ComInterop
{
    public class Program
    {
        MyCom _myCom;

        [STAThread]
        static void Main( string[] args )
        {
            new Program();
        }

        public Program()
        {
            _myCom = new MyCom();

            // this method call works
            string version = _myCom.ComMethod();

            StartThread();
        }

        private void StartThread()
        {
            Thread t = new Thread( UIRun );
            t.SetApartmentState( ApartmentState.STA );
            t.Start();
        }

        void UIRun()
        {
            TestUI window = new TestUI();
            window.Show();

            // this method call fails
            window.Title = _myCom.ComMethod();

            window.Closed += ( sender2, e2 ) 
                => window.Dispatcher.InvokeShutdown();

            System.Windows.Threading.Dispatcher.Run();
        }
    }

    class MyCom
    {
        private dynamic _com;
        public MyCom()
        {
            _com = Activator.CreateInstance(
                Type.GetTypeFromProgID( "Excel.Application" ) );
        }

        public string ComMethod()
        {
            return (string) _com.Version;
        }
    }    
}

解决方案

The problem is your program's startup thread. It creates the COM object, starts a thread, then exits. As part of the cleanup of that main thread, .NET calls CoUninitialize() and that's the end of the COM object. Getting that error is the expected result.

There's just no point in letting your main startup thread exit like that. Let it do the work now done by your own thread, problem solved.

这篇关于WPF线程:“已经与其底层RCW分离的COM对象不能被使用”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆