无法计算表达式,因为本机帧位于调用堆栈的顶部

本文关键字:调用 堆栈 顶部 于调用 表达式 计算 因为 本机 | 更新日期: 2023-09-27 18:35:56

我正在创建一个简单的窗口服务,当我去调试时,我收到错误,"无法计算表达式,因为本机帧位于调用堆栈之上。此外,当我在发布中构建服务并运行时,它只是挂起。

 static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new MyService1() };
        ServiceBase.Run(ServicesToRun);
    }

这就是程序.cs文件中的全部内容,它通常挂在ServiceBase.Run(ServicesToRun)行上。

我能够找到的所有内容都与未计算的表达式有关,因为代码已优化或必须处理 asp.net 和 response.redirect。

服务代码。

    public TruckRateClearService()
    {
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {
        tmrProcess.Enabled = true;
    }
    protected override void OnCustomCommand(int command)
    {
        base.OnCustomCommand(command);
        if (command == 129)
        {
            OnStart(null);
        }
    }
    protected override void OnStop()
    {
        tmrProcess.Enabled = false;
    }
    private void tmrProcess_Tick(object sender, EventArgs e)
    {
        tmrProcess.Enabled = false;
        try 
        {
            eventLog.WriteEntry("Clearing Truck Rates Start" + DateTime.Now.ToString());
            TruckRateClearingAgent.Process();
            eventLog.WriteEntry("Clearing Truck Rates Finished" + DateTime.Now.ToString());
        }
        catch (Exception ex)
        {
            eventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
        }
        tmrProcess.Enabled = true;
    }
    internal void Run()
    {
        tmrProcess_Tick(tmrProcess, null);
    }

内部空白运行()是最近根据Eren Ersönmez评论中的建议添加的。他的想法对于帮助调试我的逻辑非常有帮助,直到我弄清楚其余的。

我能够进入本机调用堆栈,它位于一个位置,76F17094 ret。现在我不知道这是什么,但也许其他人会。

此外,当我启动该服务并考虑将其附加到VS时,我注意到它的两个实例。一个是正常的.exe,另一个是.vshost.exe。当我启动其他服务时,我只在调试器的附加到进程部分看到.exe文件。这可能是因为一个在 v4 框架(.vshost .exe 服务)上,另一个在 v2(单.exe服务)框架上?

我相信我让它工作了。问题似乎出在我使用的计时器上。我使用的原始计时器是System.Windows.Forms计时器。我把它切换到System.Timers.Timers,一切又开始工作了。仍然无法将VS附加到它,但我仍然可以使用内部Run()方法对其进行调试。感谢所有的帮助 n.n

无法计算表达式,因为本机帧位于调用堆栈的顶部

您的主要问题是您尝试直接运行Windows服务exe。Windows 服务只能通过服务控制管理器 (SCM) 启动。为了能够在VS中调试,我推荐这样的东西:

static void Main()
{
    if (Environment.UserInteractive)
    {
        new MyService1().Run();
        Thread.Sleep(Timeout.Infinite);
    }
    else
    {
        ServiceBase.Run(new ServiceBase[] { new MyService1() });
    }
}

您将创建一个MyService1.Run方法,该方法生成一个运行服务循环的新线程。此外,您将从MyService1.Onstart中调用相同的Run方法。

该方案在由 SCM 启动时将其作为服务运行,但在 VS 中调试(或在 VS 外部直接作为 exe 运行)时将其视为普通 exe。

问题

此通知意味着线程当前正在执行非托管代码,因此不能用于计算表达式。

在某些情况下,可以等待调用返回到托管代码,然后再计算表达式。 不幸的是,在这种情况下,在您关闭服务之前不会发生这种情况。

另一种选择

您可以考虑重写 ServiceBase.OnCustomCommand 方法,并在其中放置一个断点,以便可以计算表达式。

protected override void OnCustomCommand(int command)
{
   //Debugger.Break()   <- or just put a breakpoint in here.
}

您可以按如下方式调用自定义命令:

c:'>sc control YourServiceName 129

您看到的异常意味着非托管代码正在引发异常,因此 .NET 调试器无法显示通常有用的详细信息。

你在 MyService1() 中做什么?你能在里面发布代码吗?

此外,您是否尝试通过从环境中启动服务来调试服务。那可能行不通。

我通常写这样的东西:

static void Main(params string[] args)
{
   if (args.Length > 0 && args[0] == "/console")
   {
      // Run whatever your service calls here
   }
   else
   {
      ServiceBase[] ServicesToRun;
      ServicesToRun = new ServiceBase[] { new MyService1() };
      ServiceBase.Run(ServicesToRun);
  }
}

然后在"调试"选项卡下的项目属性中,输入 /console 作为命令行参数。您应该能够单步执行应用程序并对其进行调试。您只能通过先安装服务来调试服务:http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx