System.Runtime.InteropServices.InvalidComObjectException添加和分离COM事件 [英] System.Runtime.InteropServices.InvalidComObjectException adding and detaching COM event

查看:609
本文介绍了System.Runtime.InteropServices.InvalidComObjectException添加和分离COM事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的C#项目中,我们使用的是我们开发的COM DLL.

当我们尝试通过使用运算符-="来分离由COM DLL公开的事件时",有时会引发"System.Runtime.InteropServices.InvalidComObjectException"已与其底层RCW分离的COM对象...".

我们开发了一个简单的测试项目(请参见下面的COM DLL和C#客户端代码)以进行重现此问题.
测试项目包含一个带有按钮的winform,该按钮每次单击都会附加或分离事件.多次单击按钮后,将引发异常.重现问题所需的单击次数是可变的(连续单击3分钟后,我们重现了该问题).

如果我们保留对DoubleParameter(masterDevice_.maxTemperature)的引用作为Form1类的属性一切正常.

此补丁解决了"问题,但我们仍在努力了解原因和真正含义发生,以便更好地解决它.

我们希望,我们正确地解释了这个问题.

在此先感谢您的帮助


---------- C#客户端----------

//C#示例
系统;
使用 System.ComponentModel;
使用 System.Data ;
使用 System.Drawing;
使用 System.Linq;
使用 System.Text;
使用 System.Windows.Forms;
命名空间 WindowsFormsApplication1
{
class Form1:Form
{
私有 测试;
私有 MasterDevice masterDevice_;
new MasterDevice();
test = private button1_Click(对象发送方,EventArgs e)
{

// C# Example
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ATL_TestLib;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private bool test;
        private MasterDevice masterDevice_;
        public Form1()
        {
            masterDevice_ = new MasterDevice();
            test = true;
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {

DoubleParameter doubleParameter = mastermaster_.maxTemperature;
如果(测试)
"TRUE \ n"
);
test = else
的{
doubleParameter.ValueChanged-= "FALSE \ n" );
test = true ;
}


void
maxTemperature_ValueChanged()
} br>}

                DoubleParameter doubleParameter =  masterDevice_.maxTemperature;
                if (test)
                {
                    doubleParameter.ValueChanged += new _IDoubleParameterEvents_ValueChangedEventHandle(maxTemperature_ValueChanged);
                    System.Diagnostics.Debug.Write("TRUE\n");
                    test = false;
                }
                else
                {
                    doubleParameter.ValueChanged -= new _IDoubleParameterEvents_ValueChangedEventHandle(maxTemperature_ValueChanged);
                    System.Diagnostics.Debug.Write("FALSE\n");
                    test = true;
                }
        }
    
        void
maxTemperature_ValueChanged()
        {
        }
    }
}


---------- DLL源DoubleParameter ----------

//COMDOUBLEPARAMETER
一次
#include
#include &; _ IDoubleParameterEvents_CP.H""
已定义 (_ W IN32_WCE)&& !已定义(_ CE_DCOM)&& !已定义(_ CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)

// COMDOUBLEPARAMETER
#pragma once
#include
"resource.h" // main symbols
#include "ATL_Test_i.h"
#include "_IDoubleParameterEvents_CP.H"

#if
defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)

#error " ; Windows CE平台(例如,不包含完整的DCOM支持的Windows Mobile平台)上不正确支持单线程COM对象.定义_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA以强制ATL支持创建单线程COM对象并允许使用其单线程COM对象实现.将rgs文件中的线程模型设置为免费",因为这是非DCOM Windows CE平台支持的唯一线程模型."
#endif

//COMDoubleParameter
class ATL_NO_VTABLE COMDoubleParameter:
公共 CComObjectRootEx< CComSingleThreadModel> ;,
public CComCoClass< COMDoubleParameter,& CLSID_DoubleParameter> ;,
公共 IDispatchImpl< IDoubleParameter,& IID_IDoubleParameter,& LIBID_ATL_TestLib,/* wMajor = */ 1,

#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif

// COMDoubleParameter
class ATL_NO_VTABLE COMDoubleParameter :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<COMDoubleParameter, &CLSID_DoubleParameter>,
public IDispatchImpl<IDoubleParameter, &IID_IDoubleParameter, &LIBID_ATL_TestLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,

public public CProxy_IDoubleParameterEvents< COMDoubleParameter>
{
public :
COMDoubleParameter()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_DOUBLEPARAMETER)

public IConnectionPointContainerImpl<COMDoubleParameter>,
public CProxy_IDoubleParameterEvents<COMDoubleParameter>
{
    public:
    COMDoubleParameter()
    {
    }
    DECLARE_REGISTRY_RESOURCEID(IDR_DOUBLEPARAMETER)


BEGIN_COM_MAP(COMDoubleParameter)
COM_INTERFACE_ENTRY(IDoubleParameter)
p是COM_IDFatch_ENTRY )
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT() S_OK;
}
void FinalRelease()
{{
}}
public :
BEGIN_CONNECTION_POINT_MAP(COMDoubleParameter)
CONNECTION_POINT_ENTRY( __ uuidof (_ IDoubleParameterEvents))
END_CONNECTION_POINT_MAP()
; >
OBJECT_ENTRY_AUTO( __ uuidof (DoubleParameter),COMDoubleParameter)




    BEGIN_COM_MAP(COMDoubleParameter)
        COM_INTERFACE_ENTRY(IDoubleParameter)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY(IConnectionPointContainer)
    END_COM_MAP()

    DECLARE_PROTECT_FINAL_CONSTRUCT()
    HRESULT FinalConstruct()
    {
        return S_OK;
    }
    void FinalRelease()
    {
    }
public:
    BEGIN_CONNECTION_POINT_MAP(COMDoubleParameter)
        CONNECTION_POINT_ENTRY(__uuidof(_IDoubleParameterEvents))
    END_CONNECTION_POINT_MAP()
};

OBJECT_ENTRY_AUTO(__uuidof(DoubleParameter), COMDoubleParameter)


---------- DLL Source MasterDevice ----------

//COMMASTERDEVICE
ATL_NO_VTABLE COMMasterDevice:
public CComCoClass< COMMasterDevice,& CLSID_MasterDevice> ;,
/* wMajor = */
1,/* wMinor = */ 0>
{
public :
COMMasterDevice()
<{{br>}}

DECLARE_REGISTRY_RESOURCEID(IDR_MASTERDEVICE)
DECLARE_NOT_AGGREGATABLE(COMMasterDevice)

INB ERFACE_ENTRY(IDispatch)
END_COM_MAP()

HRESULT FinalConstruct()
{
返回 S_OK;
> void FinalRelease()
private :
CComObject <; COMDoubleParameter> doubleParameter_;
公共:
STDMETHOD(get_maxTemperature)(IDoubleParameter ** pVal)
{{br> 返回 doubleParameter_.QueryInterface(pVal);
}
};
OBJECT_ENTRY_AUTO( __ uuidof (MasterDevice),COMMasterDevice)

---------- DLL源(IDL)-------- -

// COMMASTERDEVICE
class ATL_NO_VTABLE COMMasterDevice :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<COMMasterDevice, &CLSID_MasterDevice>,
public IDispatchImpl<IMasterDevice, &IID_IMasterDevice, &LIBID_ATL_TestLib, /*wMajor =*/
1, /*wMinor =*/ 0>
{
    public:
    COMMasterDevice()
    {
    }

    DECLARE_REGISTRY_RESOURCEID(IDR_MASTERDEVICE)
    DECLARE_NOT_AGGREGATABLE(COMMasterDevice)

    BEGIN_COM_MAP(COMMasterDevice)
        COM_INTERFACE_ENTRY(IMasterDevice)
        COM_INTERFACE_ENTRY(IDispatch)
    END_COM_MAP()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }
    void FinalRelease()
    {
    }
private:
    CComObject<COMDoubleParameter> doubleParameter_;
public:
    STDMETHOD(get_maxTemperature)(IDoubleParameter** pVal)
    {
        return doubleParameter_.QueryInterface(pVal);
    }
};
OBJECT_ENTRY_AUTO(__uuidof(MasterDevice), COMMasterDevice)

---------- DLL Source (IDL) ----------

//IDL文件
//ATL_Test.idl:IDL源ATL_Test
//
//MIDL工具将处理此文件,以
//生成类型库(ATL_Test.tlb)和编组代码.
导入"oaidl.idl" ;
import ;
[
对象,
uuid(0A790E23-86E5-43BB-8CF2-82A270A119C9),
对偶,
不可扩展,
helpstring("IDoubleParameter Interface" ),
pointer_default(unique)
]
interface IDoubleParameter:IDispatch {
};
[
对象,
uuid(7E484316-6282-47A3-9EA6-BAB75CC45139),
对偶,
不可扩展,
helpstring("IMasterDevice接口" ),
pointer_de fault(unique)
]
接口 IMasterDevice:IDispatch {
.[propget,id(1),helpstring()] HRESULT maxTemperature([out,retval] IDoubleParameter ** pVal);
};
[
uuid(209A3CD3-6A94-4712-B194 -612F19F7E922),
版本(1.0),
helpstring("ATL_Test 1.0类型库" )
]
库ATL_TestLib
{
[[
)uuid(928FF146-5D80-416b-BFE1-290D6CBF9223),
helpstring("_ IDoubleParameterEvents接口" )
dispinterface _IDoubleParameterEvents
{
的属性:
方法:
[id(1),helpstring(更改:d] )] void ValueChanged();
}
importlib("stdole2.tlb" ; );
uuid(7CC9CA4B-9B59-45BD-A8EE-D814571689FD),
帮助字符串("DoubleParameter类" )
> {{
)[[默认] interface IDoubleParameter;
[["MasterDevice类" )
]
coclass MasterDevice
{{br> style ="color:blue">接口
IMasterDevice;
};
};

// IDL FILE
// ATL_Test.idl : IDL source for ATL_Test
//
// This file will be processed by the MIDL tool to
// produce the type library (ATL_Test.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
    object,
    uuid(0A790E23-86E5-43BB-8CF2-82A270A119C9),
    dual,
    nonextensible,
    helpstring("IDoubleParameter Interface"),
    pointer_default(unique)
]
interface IDoubleParameter : IDispatch{
};
[
    object,
    uuid(7E484316-6282-47A3-9EA6-BAB75CC45139),
    dual,
    nonextensible,
    helpstring("IMasterDevice Interface"),
    pointer_default(unique)
]
interface IMasterDevice : IDispatch{
    [propget, id(1), helpstring("property maxTemperature")] HRESULT maxTemperature([out, retval] IDoubleParameter** pVal);
};
[
    uuid(209A3CD3-6A94-4712-B194-612F19F7E922),
    version(1.0),
    helpstring("ATL_Test 1.0 Type Library")
]
library ATL_TestLib
{
    [
        uuid(928FF146-5D80-416b-BFE1-290D6CBF9223),
        helpstring("_IDoubleParameterEvents Interface")
    ]
    dispinterface _IDoubleParameterEvents
    {
        properties:
        methods:
        [id(1), helpstring("method Value Changed")] void ValueChanged();
    }
    importlib("stdole2.tlb");
    [
        uuid(7CC9CA4B-9B59-45BD-A8EE-D814571689FD),
        helpstring("DoubleParameter Class")
    ]
    coclass DoubleParameter
    {
        [default] interface IDoubleParameter;
        [default, source] dispinterface _IDoubleParameterEvents;
    };
    [
        uuid(BB0AE53A-CDE3-4104-BA91-2A039E069D9B),
        helpstring("MasterDevice Class")
    ]
    coclass MasterDevice
    {
        [default] interface IMasterDevice;
    };
};

推荐答案

嗨GUIDOZ,

Hi GUIDOZ,

此处给出类似的帖子:

http://social.msdn.microsoft.com /Forums/en/vsx/thread/7ec92d44-afa0-4778-bea4-6cbdd658962c


这篇关于System.Runtime.InteropServices.InvalidComObjectException添加和分离COM事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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