【问题标题】:Running a long COM operation in C#, unable to remove poison message在 C# 中运行长时间的 COM 操作,无法删除毒消息
【发布时间】:2014-10-24 22:40:04
【问题描述】:

我已经为此工作了一周,并广泛使用了 StackOverflow,但我无法弄清楚。

我正在 Autodesk 产品中使用 C# 编写插件,并且我已(通过 Marshal)连接到不同的 3D 应用程序。过去我已经为其他几十个插件做到了这一点,没有问题。

这个项目是独一无二的。在不同的 3D 应用程序中,我正在一个大型模型上运行一个长时间运行的任务(文件导出)。有时需要1-60分钟。

我收到毒消息:“此操作无法完成,因为‘应用程序’没有响应。选择“切换到”并...”从技术上讲,我可以让客户端只需单击“重试”,直到它找到应用程序,但这是不可取的。

我原本以为我只是放一个 DoEvents 类型的东西,它会等待导出完成,但是在导出子运行时会出现毒消息(这是我第一次出现毒消息,所以我学习)。然后我研究了在后台线程上运行这个导出操作,测试 ThreadPool 和 Thread 操作。但是,我可以“启动”该服务,但它永远不会从不同的 3D 应用程序中导出模型。它只是永远运行。 (我从原始帖子中删除了错误消息,因为我不是在寻找解决该子问题的方法,而是在寻找我将在下面描述的内容)

最后,我尝试修改 NetMsmqBinding(我对此也一无所知,但正在努力学习它),希望它将允许的重试次数设置为更大的数字。

        System.TimeSpan TS = new System.TimeSpan(0, 30, 10);
        System.TimeSpan TB = new System.TimeSpan(10, 0, 0);
        NetMsmqBinding NMB = new NetMsmqBinding();
        NMB.MaxRetryCycles = 1000;
        NMB.ReceiveRetryCount = 1000;
        NMB.RetryCycleDelay = TS;
        NMB.OpenTimeout = TB;

但是,无论我将 NetMsmqBinding 值更改为什么,我总是同时收到“重试”消息。我一定写得不对。在其他示例中,我注意到一个包含这些值的 xml 文件,但我不知道该 xml 是什么。我也不想知道,因为我宁愿让这个在插件中运行,而不是有另一个 xml 文件来处理。

我在假设中找到了很多关于如何处理这个问题的例子(很多 console.write BS),但实际上没有一个具体的例子,即长时间运行的 COM 进程正在中断主要的 C# 实用程序。

我真的很想弄清楚如何将重试频率和周期重置为持续更长时间,这样就不会出现有害消息。我该怎么做?

这里有更多代码,提供一些上下文:

namespace Testing_V0
{
    [PluginAttribute("Testing_V0R1", "ADSK", ToolTip = "Testing the plugin", DisplayName = "Testing the plugin")]
    [AddInPluginAttribute(AddInLocation.AddIn)]
    public class MyPlugin : AddInPlugin
    {
        public override int Execute(params string[] parameters)
        {
        System.TimeSpan TS = new System.TimeSpan(0, 30, 10);
        System.TimeSpan TB = new System.TimeSpan(10, 0, 0);
        NetMsmqBinding NMB = new NetMsmqBinding();
        NMB.MaxRetryCycles = 1000;
        NMB.ReceiveRetryCount = 1000;
        NMB.RetryCycleDelay = TS;
        NMB.OpenTimeout = TB;

        //NMB.ReceiveErrorHandling = ReceiveErrorHandling.Drop;

     //Do the Export process here
     }
    }
}

【问题讨论】:

  • 这不是一个“毒消息”,只是来自调试器的 MDA 通知。 ContextSwitchDeadlock 托管调试器助手旨在检测方法调用在 60 秒内未完成时可能出现的死锁。你已经知道是什么原因造成的,你故意让你的程序挂起。 Debug + Exceptions,展开“Managed Debugging Exceptions”节点。取消勾选警告,您将永远不必再查看它。
  • 感谢您提供这些信息,但我对帖子末尾的 netmsmqbinding 问题更感兴趣。我不认为这是您提到的帖子的重复。
  • 永远不要问两个问题。您可以重新询问第二个。
  • 我没有问两个问题。我只是解释了我所经历的所有步骤,所以我看起来不像只是在没有调查的情况下发布问题。重申一下,我只问了一个问题,那就是:“我真的很想弄清楚如何重置重试频率和周期以持续更长时间,这样就不会出现有害消息。我该怎么做?”
  • 能否去掉标题中的“重复”并去掉不相关解决方案的链接?

标签: c# com marshalling netmsmqbinding


【解决方案1】:

因为我没有更多的时间来处理这个问题,所以我将解释我是如何解决这个问题的。这可能不是解决此问题的可取方法,但它有一些优势。

几个月前,在一个不相关的项目中,我做了一个类似的应用程序,我导出了相同的文件格式,但来自控制台应用程序。控制台应用程序没有像 AutoDesk 产品的 dll 中出现的这些问题。

使用我从控制台应用程序导出中记住的内容,我制作了一个新的小型控制台应用程序 exe,它只执行文件导出。然后我在父 dll 中使用 System.IO.Process.Start(file.exe, "arguments") 命令来触发可执行文件。

这是摆脱弹出消息的一种非常迂回的方式,但也有一些优点。可执行文件运行导出,而 C# DLL 继续。这允许我运行一个简单的文件存在循环,直到文件出现在目录中,然后继续。我在 C# DLL UI 中放置了一个进度计数器,它在导出器运行时为客户端提供了一个很好的稳定读数。

就像我说的,这并不理想,但目前这对我有用。

【讨论】:

  • 对于反对者,如果您知道更好的解决方案,请务必发布答案。当您无法提出解决方案时,很容易投反对票。
  • 我仍在寻找更好的方法来做到这一点。否决投票者可以发布解决方案吗?
  • 我仍然无法获得任何东西来修改 netmsmqbinding 参数。谁能帮帮我?
  • 我仍在寻找解决方案。有人在吗?
猜你喜欢
  • 2011-11-30
  • 2022-07-12
  • 2011-12-11
  • 1970-01-01
  • 2021-10-29
  • 2013-01-14
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多