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

C# 无法计算表达式,因为本机框架位于调用堆栈的顶部,c#,windows-services,C#,Windows Services,我正在创建一个简单的窗口服务,当我去调试时,我得到一个错误,“无法计算表达式,因为本机框架位于调用堆栈的顶部。”。另外,当我在发行版中构建服务并运行它时,它只是挂起 static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new MyService1() }; ServiceBase.Run(ServicesToRun);

我正在创建一个简单的窗口服务,当我去调试时,我得到一个错误,“无法计算表达式,因为本机框架位于调用堆栈的顶部。”。另外,当我在发行版中构建服务并运行它时,它只是挂起

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

        ServiceBase.Run(ServicesToRun);
    }
这就是Program.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);
    }
内部Void Run()是最近根据Eren Ersönmez评论中的建议添加的。他的想法非常有助于调试我的逻辑,直到我能找出其余的问题

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

另外,当我启动服务并将其连接到VS时,我注意到它的两个实例。一个是normal.exe,另一个是.vshost.exe。启动其他服务时,我只在调试器的“附加到进程”部分中看到.exe文件。这可能是因为一个在v4框架(.vshost.exe服务)上,另一个在v2(single.exe服务)框架上


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

问题

此通知表示线程当前正在执行非托管代码,因此无法用于计算表达式

protected override void OnCustomCommand(int command)
{
   //Debugger.Break()   <- or just put a breakpoint in here.
}
在某些情况下,您可以等待调用返回托管代码,然后再计算表达式。不幸的是,在这种情况下,在关闭服务之前不会发生这种情况

备选方案

您可以考虑重写该方法并在其中放置断点,这样您就可以对表达式进行评估。

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

您看到的异常意味着非托管代码正在引发异常,因此.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);
  }
}
static void Main()
{
    if (Environment.UserInteractive)
    {
        new MyService1().Run();
        Thread.Sleep(Timeout.Infinite);
    }
    else
    {
        ServiceBase.Run(new ServiceBase[] { new MyService1() });
    }
}

然后在“调试”选项卡下的“项目属性”中,输入
/console
作为命令行参数。您应该能够进入应用程序并调试它。您只能通过先安装来调试服务:

您的主要问题是试图直接运行windows service exe。Windows服务只能通过服务控制管理器(SCM)启动。为了能够在VS中进行调试,我建议如下:

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);
  }
}
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。

我最初是重新安装服务并将VS附加到它上的。我参考了Eren的建议,并将其添加到我的代码中,这样我就可以使用普通的调试器了。但是,我还没有找到任何非托管代码。进入项目的属性并打开“允许不安全代码”是否安全?请尝试此处的说明:我将所有内容放入并执行了命令,结果成功了。然而,当我退出该功能时,它不会让我再前进。当我转到Debug->Break All时,它正处于服务失败的同一点。我想我做的不对。你看到了什么样的失败?挂起还是异常?与我在“无法计算表达式…”之前得到的相同。服务将挂在ServiceBase上。运行(ServicesToRun)部分。哦,我以为你只是想使用快速观察窗口。现在听起来您希望在应用程序代码中设置断点。是否为要调试的程序集加载了符号?(您可以在输出窗口(ctrl+alt+o)中找到)符号被加载,我只是无法在Program.cs文件中获得要触发的断点。