其他分享
首页 > 其他分享> > 从WinForms GUI线程调用COM线程上的方法有问题吗?

从WinForms GUI线程调用COM线程上的方法有问题吗?

作者:互联网

我用.NET编写的COM组件遇到了麻烦,引发了如下警告:

Context 0x15eec0 is disconnected. No
proxy will be used to service the
request on the COM component. This may
cause corruption or data loss. To
avoid this problem, please ensure that
all contexts/apartments stay alive
until the application is completely
done with the RuntimeCallableWrappers
that represent COM components that
live inside them.

看来这是由于我的GUI线程在COM线程中调用函数而没有必要的同步引起的.作为参考,我使用http://msdn.microsoft.com/en-us/library/ms229609%28VS.80%29.aspx中设置的准则在COM组件中创建GUI线程.

我的代码如下所示:

class COMClass {
  // this is called before SomeMethod
  public void Init() {
    ComObject comObject = new ComObject(); // this is imported from a TLB

    // I create my GUI thread and start it as in the MSDN sample
    Thread newThread = new Thread(new ThreadStart(delegate() {
      Application.Run(new GUIForm(comObject));
    }));
  }

  public void SomeMethod(){
    comObject.DoSomething();               // this is where the error occurs
  }
}

class GUIForm : Form {
  ComObject com;
  public GUIForm(ComObject com) {comObject = com;}

  public void SomeButtonHandler(object sender, EventArgs e) {
    comObject.SomeMethod();  // call on the GUI thread but the com object is bound to the COM thread...
  }
}

有解决此问题的既定方法吗?调用GUI没问题(Invoke / BeginInvoke),但是以其他方式调用似乎更困难…

编辑:也不是以任何方式修改COM对象的选项.

解决方法:

从您的代码片段中还不清楚如何调用所有重要的Init()方法以及如何启动线程.显然,创建COM对象的线程与进行SomeMethod()调用的线程不同.进一步假设COM服务器是单元线程,COM需要将SomeMethod()调用编组到创建对象的线程.称为Init()的那个.如果该线程不再运行,则会发生欢闹.

有一个明显的问题,您忘记了调用Thread.SetApartmentState().

鉴于COM已经封送线程间调用,因此您可能无法通过启动自己的线程获得任何好处.如果它拒绝支持COM服务器,则无法神奇地使其成为多线程.

标签:com,com-interop,c,net,winforms
来源: https://codeday.me/bug/20191210/2100366.html