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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10851719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:31:50  来源:igfitidea点击:

Cannot evaluate expression because a native frame is on top of the call stack

c#windows-services

提问by Tim B

I'm creating a simple window service and when I go to debug I get the error, "Cannot evaluate expression because a native frame is on top of the call stack.". Also, when I build the service in Release and run it just hangs.

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

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

        ServiceBase.Run(ServicesToRun);
    }

Thats all that is in the Program.cs file, where it normally gets hung on the ServiceBase.Run(ServicesToRun) line.

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

Everything I've been able to find only relates to the expression not being evaluated because the code is optimized or having to deal with asp.net and response.redirect.

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

Code for the Service.

服务代码。

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

The Internal Void Run() was added just recent on the suggestion in the comments by Eren Ers?nmez. His idea has been very helpful for helping debug my logic until I can figure the rest out.

Internal Void Run() 是最近根据 Eren Ers?nmez 评论中的建议添加的。他的想法对帮助调试我的逻辑非常有帮助,直到我能弄清楚其余部分。

I was able to get the into the Native call stack and it sits on one location, 76F17094 ret. Now I have no idea what this is but maybe someone else will.

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

Also, when I start the service and look into attaching it to VS I'm noticing two instances of it. One is the normal .exe and another is a .vshost.exe. When I start other services I only see the .exe file in the Attach to process part of the debugger. Could this be because one is on the v4 Framework ( .vshost .exe service ) and another on the v2 ( single .exe service ) Framework?

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

I believe I got it working. It seems that the problem lied with the timer I was using. The original timer I was using was a System.Windows.Forms timer. I switched it to System.Timers.Timers and everything started working again. Still cant attach VS to it but I can debug it still by using the Internal Run() method. Thanks for all the help n.n

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

回答by agent-j

The problem

问题

This notification means that the thread is currently executing unmanaged code, and therefore cannot be used to evaluate the expression.

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

In some situations, you could wait for the call to return to managed code before evaluating the expression. Unfortunately, in this situation, that won't happen until you shut down the service.

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

An Alternative

替代

You might consider overriding the ServiceBase.OnCustomCommandmethod and putting a breakpoint there so you can evaluate your expression.

您可能会考虑覆盖ServiceBase.OnCustomCommand方法并在那里放置一个断点,以便您可以评估您的表达式。

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

You can invoke the custom command as follows:

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

c:\>sc control YourServiceName 129

回答by greg84

The exception you're seeing means that unmanaged code is throwing an exception, so the .NET debugger can't show you the usual useful details.

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

What are you doing in MyService1() ? Can you post the code inside it?

你在 MyService1() 做什么?你能把代码贴在里面吗?

Also are you trying to debug the service by just starting it from the environment. That might not work.

您是否也试图通过从环境中启动服务来调试服务。那可能行不通。

I usually write something like this:

我通常这样写:

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

Then in the project properties under the Debug tab enter /consoleas the command line arguments. You should be able to step into the application and debug it. You can only debug a service by installing it first: http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx

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

回答by Eren Ers?nmez

Your main problem is that you're trying to directly run a windows service exe. Windows services can only be started via Service Control Manager (SCM). In order to be able to debug in VS, I'd recommend something like this:

您的主要问题是您试图直接运行 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() });
    }
}

You'd create a MyService1.Runmethod which spawns a new thread that runs the service loop. Also, you'd call the same Runmethod from within the MyService1.Onstart.

您将创建一个MyService1.Run方法,该方法生成一个运行服务循环的新线程。此外,您可以RunMyService1.Onstart.

This scheme runs it as a service when being started by SCM, but treats it like a normal exe when being debugged in VS (or being run directly as an exe outside VS).

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