Le service Windows .NET doit utiliser STAThread
J'ai créé un Service Windows qui fera appel à certains composants COM, donc j'ai marqué [STAThread] à la fonction Principale. Toutefois, lorsque la minuterie se déclenche, il les rapports de MTA et les appels COM échouer. Comment puis-je résoudre ce problème?
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
}
}
source d'informationauteur Walter Williams
Vous devez vous connecter pour publier un commentaire.
Les Services sont exécutés par le service windows le système d'hébergement, qui s'exécute à l'aide de threads MTA. Vous ne pouvez pas contrôler cela. Vous devez créer un nouveau Fil et définir sa N'à STAet de faire votre travail sur ce fil.
Voici une classe qui étend la classe ServiceBase qui fait cela:
Noter que ce code ne fait pas arrêter le service, il arrête le chronomètre. Il pourrait y avoir beaucoup de travail encore fait sur plusieurs threads. Par exemple, si votre travail a consisté en l'exécution de plusieurs requêtes à côté d'un grand de la base de données vous pouvez finir par s'écraser parce que vous avez trop de threads en cours d'exécution au même moment.
Dans ce genre de situation, je voudrais créer un nombre de threads STA (peut-être 2x le nombre de cœurs de départ), qui surveillent un thread-safe file d'attente pour les éléments de travail. Le timer tick événement serait responsable du chargement de cette file d'attente avec le travail à faire à faire.
Tout dépend de ce que vous êtes en train de faire toutes les dix secondes, si oui ou non elle doit être remplie de la prochaine fois que la minuterie de tiques, ce que vous devriez faire dans cette situation, etc etc.
Paramètre de l'attribut STAThread ne fonctionnera pas sur un service. Il n'est pas traité de la même façon qu'une demande, de sorte que ce sera ignoré.
Ma recommandation serait à effectuer manuellement un thread séparé pour votre service, définir son appartement de l'état, et passer le tout. De cette façon, vous pouvez définir le thread STA correctement.
Cependant, il y aura une autre question, ici vous devrez retravailler la façon dont votre service des œuvres. Vous ne pouvez pas simplement utiliser un Système.Le filetage.Minuterie exemple pour le timing, il fonctionne sur un thread séparé, qui ne sera pas de STA. Lors de sa écoulé événement se déclenche, vous allez travailler sur un autre, non-thread STA.
Au lieu de faire votre travail dans l'événement de minuterie, vous aurez probablement envie de faire votre travail principal dans le fil que vous avez créer explicitement. Vous pouvez avoir un événement de réinitialisation dans ce thread qui bloque, et vous avez votre minuterie "set" pour permettre à votre logique à exécuter dans le thread STA.
Qui ne peuvent pas travailler dans un service, le thread qui appelle votre méthode main() avait déjà été lancé par le service gestionnaire. Vous aurez besoin de créer un thread séparé qui est initialisé avec Fil.SetApartmentState() et les pompes à une boucle de message.
En regardant un exemple similaire: http://www.aspfree.com/c/a/C-Sharp/Creating-a-Windows-Service-with-C-Sharp-introduction/1/
Que faire si votre main est...
et déplacez votre timer start /stop-out, des événements...
Il signale que c'est à l'aide de STA. Il est basé sur la Volonté de la suggestion et de http://en.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1:_Use_a_Separate_Thread