【问题标题】:Service Broker / External Application Activation and Visual Studio DebuggingService Broker / 外部应用程序激活和 Visual Studio 调试
【发布时间】:2016-03-15 14:55:31
【问题描述】:

我刚搬到一个使用大量 Service Broker 功能的代码库。

我的 EAService.config 设置如下

<ApplicationService name="NotificationTest" enabled="true">
  <OnNotification>
    <ServerName>MyServer\MyInstance</ServerName>
    <DatabaseName>MyDatabase</DatabaseName>
    <SchemaName>dbo</SchemaName>
    <QueueName>MyQueueName</QueueName>
  </OnNotification>
  <LaunchInfo>
    <ImagePath>C:\SomeFolder\SomeConsoleApp.exe</ImagePath>
    <CmdLineArgs>myCommandLineArg1</CmdLineArgs>
    <WorkDir>C:\SomeFolder\</WorkDir>
  </LaunchInfo>
  <Concurrency min="1" max="1" />
</ApplicationService>   

当我尝试调试上述代码时,我的问题就出现了。

由于 Service Broker 外部激活器 (C:\Program Files\Service Broker\External Activator\Bin\ssbeas.exe) 正在实例化代码....这不是我可以运行的东西(据我所知)在“调试模式”中等待调用进入并设置断点。

比如有个WEBAPI的项目,我可以做传统的Start/Debug,在ApiController/Method上下断点,当有请求进来的时候,会在断点上断,我可以接从那里调试。

使用 Service Broker,它正在实例化一些 .exe....而 .exe 可能会如此快速地打开和关闭,我无法“搜索和查找”以将调试器附加到它。

我还想,“也许我会让 Service Broker 向 WCF 服务发送消息”,但根据我在这篇 SOF 帖子中读到的内容,这看起来不太可能实现或非常麻烦:

Service Broker and WCF interoperability

我是否可以在 EAService.config 中进行上述设置并让调试器中断,如下图所示?

或者有没有人想出一种非 hacky 的方法来调试由 Service Broker “激活”的 C# 代码?

【问题讨论】:

  • 在这种情况下,我总是走“老派”,我用许多写入日志的“跟踪”语句来检测代码。它是核心且缓慢的,但它确实有效。不过需要大量的耐心和毅力。
  • 老派。这就是我害怕的。 javascript:alert("stinkFactorValue=" + stinkFactor);
  • 这是一种精通的好技术,因为它几乎是唯一适用于几乎所有条件和环境的技术。

标签: c# sql-server visual-studio sql-server-2012 service-broker


【解决方案1】:

您有多种选择:

A.修改 EAConfig 以在调试器下启动程序:

  <ImagePath>C:\PathToDebugger\YourDebuggerOfChoice.exe</ImagePath>
  <CmdLineArgs>C:\SomeFolder\SomeConsoleApp.exe myCommandLineArg1</CmdLineArgs>

B.使用 GFlags 图像执行选项将调试器添加到您的应用程序
C. 使用Debugger.Launch()从应用程序本身启动调试器
D. 禁用 EA 并直接从 VS (F5) 运行应用程序,以进行调试,然后重新启用 EA。

【讨论】:

  • 我构建了相当多的复杂 SSBEA 场景。绝对是 D,更好的是,将所有“工作代码”包装在一个单独的程序集中,保持激活的控制台应用程序(exe)尽可能小,同时处理 AppDomain.UnhandledException Event
  • 我昨天尝试了“B”.....它会附加调试器,但不会在任何地方“中断”。 A是一个全新的想法,所以谢谢你。我尝试的一个想法是 A 和 C 的组合。编辑 CmdLineArgs 以包含类似“DEBUGME”的内容,然后在 Main 方法中执行此操作。 int index = Array.FindIndex(args, x => x.Equals("DEBUGME", StringComparison.OrdinalIgnoreCase)); if (index > -1) { System.Diagnostics.Debugger.Launch(); } 这是一个 hack,但它有效。
  • @granadaCoder 选项 B 取决于使用的调试器。我不熟悉 VS 调试命令行,我是 WinDbg 的粉丝,我会使用 -g 或不“最初中断”。但我认为在 WinDbg 中进行 C# 调试并不完全是一种“乐趣”......
  • 另外,警告:在调试时,您很可能会让队列监视器进入“通知”状态。见rusanu.com/2008/08/03/understanding-queue-monitors
  • @StefanAnghel 很有趣。如果您对 SSB 有任何疑问,请随时与我联系,我现在常驻布加勒斯特。
【解决方案2】:

所以这就是我最终得到的……作为我能找到的最一致的方法。

    static void Main(string[] args)
    {

        try
        {

#if DEBUG
            int index = Array.FindIndex(args, x => x.Equals("LAUNCHDEBUGGER", StringComparison.OrdinalIgnoreCase));
            if (index > -1)
            {
                System.Diagnostics.Debugger.Launch();
            }
#endif

 <LaunchInfo>
    <ImagePath>C:\SomeFolder\SomeConsoleApp.exe</ImagePath>
    <CmdLineArgs>myCommandLineArg1 LAUNCHDEBUGGER</CmdLineArgs>
    <WorkDir>C:\SomeFolder\</WorkDir>
  </LaunchInfo>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 2012-11-16
    • 2015-12-10
    • 2012-11-18
    相关资源
    最近更新 更多