2012-06-01 9 views
5

Tworzę prostą usługę okna i kiedy idę do debugowania, pojawia się błąd "Nie można ocenić wyrażenia, ponieważ natywna ramka jest nad wywołaniem stos.". Ponadto, gdy buduję usługę w wersji Release i uruchamiam, po prostu się zawiesza.Nie można ocenić wyrażenia, ponieważ natywna ramka znajduje się na wierzchu stosu wywołań

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

     ServiceBase.Run(ServicesToRun); 
    } 

To wszystko, co jest w pliku Program.cs, gdzie normalnie dostaje wisiał na linii (ServicesToRun) ServiceBase.Run.

Wszystko, co udało mi się znaleźć, odnosi się tylko do wyrażenia nie podlegającego ocenie, ponieważ kod jest zoptymalizowany lub ma do czynienia z asp.net i response.redirect.

Kod usługi.

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

Wewnętrzny Void Run() został dodany niedawno w sugestii w komentarzach Eren Ersönmez. Jego pomysł był bardzo pomocny w pomaganiu w debugowaniu mojej logiki, dopóki nie wymyślę reszty.

Udało mi się dostać do rodzimego stosu wywołań i znajduje się on w jednej lokalizacji, 76F17094 ret. Teraz nie mam pojęcia, co to jest, ale może ktoś inny.

Również po uruchomieniu usługi i rozważeniu dołączenia jej do VS zauważam dwa jej wystąpienia. Jednym z nich jest normalny .exe, a drugim jest plik .vshost.exe. Kiedy uruchamiam inne usługi, widzę tylko plik .exe w Załączniku, aby przetworzyć część debuggera. Czy to możliwe, ponieważ jeden znajduje się na platformie v4 (usługa .vshost .exe), a drugi na platformie v2 (pojedyncza usługa .exe)?

Wierzę, że to działa. Wygląda na to, że problem tkwił w zegarku, z którego korzystałem. Oryginalny czasomierz, którego używałem, to timer System.Windows.Forms. Przełączyłem go na System.Timers.Timers i wszystko zaczęło działać. Nadal nie mogę dołączyć VS do niego, ale mogę debugować go nadal za pomocą metody Internal Run(). Dzięki za wszelką pomoc N, N

Odpowiedz

2

Problem

Powiadomienie to oznacza, że ​​wątek jest aktualnie wykonywanie kodu niezarządzanego, a zatem nie mogą być wykorzystane do oceny ekspresji.

W niektórych sytuacjach przed wykonaniem oceny wyrażenia można poczekać na powrót do zarządzanego kodu. Niestety, w tej sytuacji tak się nie stanie, dopóki nie zamkniesz usługi.

Alternatywa

Można rozważyć przesłanianie metody ServiceBase.OnCustomCommand i oddanie punkt przerwania tam, więc można ocenić swój wyraz.

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

można wywołać polecenie niestandardowe następująco:

c:\>sc control YourServiceName 129 
+0

Położyłem wszystko i wykonałem polecenie i zadziałało. Jednak, gdy wyszłam z funkcji, nie pozwoliłaby mi dalej posuwać się naprzód. A kiedy poszedłem do Debugowania -> Break All, było to w tym samym momencie, w którym usługa nie działała. Myślę, że robię coś niepoprawnego tutaj. –

+0

Jakiego rodzaju niepowodzenia widzisz? Hang lub wyjątek? –

+0

To samo co robiłem przed "Nie można ocenić wyrażenia ...". Czy usługa będzie po prostu zawieszona na części ServiceBase.Run (ServicesToRun). –

0

wyjątkiem jesteś oznacza, że ​​kod jest niekontrolowana rzuca wyjątek widząc, więc debugera .NET nie może pokazać zwykły przydatne szczegóły.

Co robisz w MyService1()? Czy możesz umieścić w nim kod?

Próbujesz też debugować usługę, uruchamiając ją ze środowiska. To może nie działać.

zazwyczaj napisać coś takiego:

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

Następnie we właściwościach projektu na karcie Debug wejść /console jako argumentów wiersza poleceń. Powinieneś być w stanie wejść do aplikacji i debugować ją. Możesz tylko debugować usługę, instalując ją najpierw: http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx

+0

Pierwotnie ponownie instalowałem usługę i dołączałem do niej VS. Spojrzałem na radę Eren i dodałem to do mojego kodu, więc mogłem po prostu użyć zwykłego debuggera. Jednak nie znalazłem jeszcze żadnego niezarządzanego kodu. Czy byłoby bezpiecznie wejść do właściwości projektu i włączyć opcję "Zezwalaj na niebezpieczny kod"? –

+0

Wypróbuj instrukcje tutaj: http://msdn.microsoft.com/en-us/library/tdw0c6sf(v=vs.80).aspx – greg84

2

Twoim głównym problemem jest to, że próbujesz bezpośrednio uruchomić usługę systemu Windows exe. Usługi Windows można uruchamiać tylko za pomocą Service Control Manager (SCM). Aby móc debugowania w VS, polecam coś takiego:

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

Można by stworzyć MyService1.Run metodę, która spawns nowego wątku, który uruchamia pętlę usług. Można również nazwać tę samą metodę Run z poziomu MyService1.Onstart.

Ten schemat uruchamia go jako usługę, gdy jest uruchamiany przez SCM, ale traktuje go jak normalny exe podczas debugowania w VS (lub jest uruchamiany bezpośrednio jako exe poza VS).

Powiązane problemy