【问题标题】:C# Visio Interop, event handlers not being calledC# Visio 互操作,未调用事件处理程序
【发布时间】:2013-07-18 04:30:41
【问题描述】:

我编写了一个使用 Visio 互操作的 C# 应用程序。我遇到了一个令我困惑的与事件相关的问题。 重现步骤:

  1. 启动 Visio
  2. 启动我的应用程序。检索 Visio 实例,可以使用对象模型,并在我的应用中接收和处理事件。
  3. 关闭我的应用 - 让 Visio 保持打开状态。
  4. 启动我的应用程序。检索到 Visio 实例并且可以使用对象模型,但我的应用未收到事件。

当我的应用打开时,它会使用以下方法检索打开的 Visio 应用的实例:

visioApp = (Microsoft.Office.Interop.Visio.Application)Marshal.GetActiveObject("Visio.Application");

我像这样注册事件:

visioApp.DocumentOpened += new EApplication_DocumentOpenedEventHandler(onDocOpened);

当我的应用关闭时,我会像这样取消注册事件:

visioApp.DocumentOpened -= onDocOpened;
visioApp = null;

当我的应用程序关闭时,我似乎没有正确取消注册/让实例离开,但这只是一个猜测。当我的应用程序第二次启动时,我没有收到任何错误 - 它只是不响应事件。我无法在网上找到任何进一步的相关信息(可能只是没有搜索正确的术语)。任何帮助是极大的赞赏!我会提供更多可能有用的信息。

@Oscars 的回答是正确的:

 Marshal.FinalReleaseComObject(_ap);

但是我还有一个问题。 Marshal.finalReleaseComObject 在类析构函数中被调用,显然在应用程序关闭序列中调用得太晚(即使我强制垃圾收集),并且没有正确释放引用。我现在更早地调用了这段代码(在 MainForm_Closing 事件中),它运行良好。感谢您的帮助!

【问题讨论】:

    标签: c# visio


    【解决方案1】:

    【讨论】:

    • 我认为这很可能是个问题
    • @Oscar 我实际上尝试过 Marshal.ReleaseComObject 但它似乎在我的应用程序中不起作用。但是,我构建了一个测试应用程序,该应用程序仅检索对 visio 的引用,响应事件,并如您提到的那样释放 visio 引用。这完美无瑕。我将不得不对我的代码进行更多挖掘,以确保我已正确释放通过互操作获得的所有对象(文档、工作表、形状等)。谢谢你的帮助!至少现在我走在了正确的轨道上!
    • 记住 2 点规则。祝你好运!
    • 在我的测试应用程序中,如果我未能取消注册事件,我只会导致问题发生。我可以注释掉 visioApp = null;和 Marshal.ReleaseComObject(visioApp);并且问题不会发生。有趣的。我希望抛出一个异常来说明问题!
    • 两点法则!我不知道 COM 对象是非托管的!这将挽救我的生命!现在去清理我的代码......谢谢。
    猜你喜欢
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    相关资源
    最近更新 更多