2012-06-01 20 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文件。

相關問題