.NET Windows-Dienst verwenden muss STAThread
Habe ich einen Windows-Service, der Aufruf an einige COM-Komponenten, so dass ich getaggt [STAThread] an die Main-Funktion. Allerdings, wenn der timer feuert, berichtet MTA und die COM-Aufrufe fehl. Wie kann ich dieses Problem beheben?
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
namespace MyMonitorService
{
public class MyMonitor : ServiceBase
{
#region Members
private System.Timers.Timer timer = new System.Timers.Timer();
#endregion
#region Construction
public MyMonitor ()
{
this.timer.Interval = 10000; //set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
}
#endregion
private void timer_Elapsed (object sender, ElapsedEventArgs e)
{
EventLog.WriteEntry("MyMonitor", String.Format("Thread Model: {0}", Thread.CurrentThread.GetApartmentState().ToString()), EventLogEntryType.Information);
}
#region Service Start/Stop
[STAThread]
public static void Main ()
{
ServiceBase.Run(new MyMonitor());
}
protected override void OnStart (string[] args)
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Started", EventLogEntryType.Information);
this.timer.Enabled = true;
}
protected override void OnStop ()
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Stopped", EventLogEntryType.Information);
this.timer.Enabled = false;
}
#endregion
}
}
InformationsquelleAutor der Frage Walter Williams | 2010-01-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dienstleistungen werden von den windows-Dienst hosting-system, das läuft mit MTA-threads. Die Sie nicht kontrollieren können. Sie erstellen eine neue Thread und seine ApartmentState zu STAund tun Sie Ihre Arbeit an diesem thread.
Hier ist eine Klasse, die Sie erweitert ServiceBase, das dies tut:
Hinweis: dieser code eigentlich nicht " den Dienst beenden, wird der timer angehalten. Es könnte sein, viel Arbeit noch getan wird, auf die mehrere threads. Zum Beispiel, wenn Ihre Arbeit Bestand in der Ausführung mehrerer Abfragen aus einer großen Datenbank, können Sie am Ende Abstürzen, weil Sie zu viele threads gleichzeitig laufen.
In einer situation wie dieser, würde ich erstellen Sie eine Reihe Reihe von STA-threads (vielleicht 2x die Anzahl der Kerne zu Beginn mit) welcher monitor eine thread-sichere Warteschlange für Arbeitsaufgaben. Die timer-tick-event wäre für die Beladung verantwortlich, dass die Warteschlange mit der Arbeit benötigen, getan.
Es hängt alles davon ab, was Sie eigentlich tun alle zehn Sekunden, ob oder nicht es sollte abgeschlossen sein, das nächste mal, wenn der timer "tickt", was Sie in dieser situation tun sollten, etc. etc.
InformationsquelleAutor der Antwort Will
Einstellung das STAThread-Attribut wird nicht auf einem service. Es ist nicht die gleiche Weise behandelt wie eine Anwendung, so wird dies ignoriert.
Meine Empfehlung wäre manuell machen einen separaten thread für den Dienst, seine Wohnung Stand, und bewegen Sie alles in sich hinein. Auf diese Weise können Sie die thread-STA-richtig.
Gibt es jedoch ein weiteres Problem hier - müssen Sie überarbeiten die Art, wie Ihr Dienst funktioniert. Können Sie nicht einfach eine System.Threading.Timer Beispiel für das timing - es läuft in einem separaten thread, der nicht von STA. Wenn seine elapsed-Ereignis ausgelöst wird, arbeiten Sie auf eine andere, nicht-STA-thread.
Anstatt das zu tun Ihre Arbeit in der timer-Ereignis ein, werden Sie wahrscheinlich wollen, um Ihre Haupt-Arbeit in den Faden, den Sie erstellen, ausdrücklich. Sie können über eine reset-Ereignis in diesem thread, der blockiert, und haben Sie Ihre timer "setzen", damit Sie Ihre Logik zum ausführen der in dem STA-thread.
InformationsquelleAutor der Antwort Reed Copsey
Das kann nicht funktionieren in einem service, der thread ruft die Methode Main() wurde bereits von der service-manager. Sie müssen, um einen eigenen thread initialisiert Thread.SetApartmentState() und Pumpen eine message-loop.
InformationsquelleAutor der Antwort Hans Passant
Blick auf ein ähnliches Beispiel: http://www.aspfree.com/c/a/C-Sharp/Creating-a-Windows-Service-with-C-Sharp-introduction/1/
Was ist, wenn dein main ist...
und bewegen Sie Ihre timer start /stop out des events...
InformationsquelleAutor der Antwort Tim Hoolihan
Dieser Berichte, dass es mit STA. Es basiert auf Wird ' s Vorschlag und http://en.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1:_Use_a_Separate_Thread
InformationsquelleAutor der Antwort Walter Williams