2012-06-01 19 views
5

我正在创建一个简单的窗口服务,并且当我去调试时,出现错误“无法评估表达式,因为原生框架位于调用顶部叠加。“。另外,当我在Release中构建服务并运行时,它只是挂起。无法评估表达式,因为原生框架位于调用栈顶部

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

内部空隙的run()加入只是最近在由二连Ersönmez的意见建议。他的想法对于帮助调试我的逻辑非常有帮助,直到我能够找出其他问题。

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

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

我相信我得到了它的工作。这个问题似乎与我正在使用的计时器有关。我使用的原始计时器是一个System.Windows.Forms计时器。我将它切换到System.Timers.Timers并且所有事情都再次开始工作。仍然不能附加VS,但我仍然可以通过使用内部运行()方法进行调试。感谢所有帮助的N,N-

回答

2

问题

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

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

另类

你可能会考虑重写ServiceBase.OnCustomCommand方法,并把一个断点,所以你可以评估你的表现。

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

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

c:\>sc control YourServiceName 129 
+0

我放了一切,并执行命令,它的工作。但是,当我走出这个职能时,它不会让我进一步前进。而当我去Debug-> Break All时,它正处于服务失败的同一时刻。我想我在这里做的不正确。 –

+0

你看到了什么样的失败?挂起或异常? –

+0

就像我之前得到的“无法评估表达式......”一样。服务是否会挂在ServiceBase.Run(ServicesToRun)部分。 –

0

你看到非托管代码抛出一个异常,表示异常,所以.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

+0

我最初重装服务并附上VS。我看了Eren的建议,并将其添加到我的代码中,这样我就可以使用普通的调试器。但是,我还没有发现任何非托管代码。进入项目的属性并关闭“允许不安全的代码”是否安全? –

+0

请尝试此处的说明:http://msdn.microsoft.com/en-us/library/tdw0c6sf(v=vs.80).aspx – greg84

2

您的主要问题是您试图直接运行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文件。

相关问题