Thread Schlaf-und Windows-Dienste
Arbeite ich an einem Windows-Dienst, der einige Probleme mit Thread.Sleep()
so dass ich dachte, ich würde versuchen, einen timer zu verwenden, anstatt, wie diese Frage empfiehlt:
Mit Thread.Sleep() in einem Windows-Dienst
Sache ist, es ist mir nicht ganz klar, wie könnte man dies umsetzen. Ich glaube, das ist der Weg, aber ich wollte nur um sicher zu gehen:
'' Inside The Service Object
Dim closingGate As System.Threading.AutoResetEvent
Protected Overrides Sub OnStart(ByVal args() As String)
Dim worker As New Threading.Thread(AddressOf Work)
worker.Start()
End Sub
Protected Sub Work()
Dim Program = New MyProgram()
closingGate = New System.Threading.AutoResetEvent(False)
Program.RunService(closingGate)
End Sub
Protected Overrides Sub OnStop()
closingGate.Set()
End Sub
'' Inside My Programs Code:
Public Sub RunService(closingGate As AutoResetEvent)
Dim tmr As New Timer
'' ...and so on
closingGate.WaitOne()
End Sub
Abgesehen von VB.Net (Scherz, aber ich würde mit C#, wenn ich könnte.) bin ich auf dem richtigen Weg? Ist das besser als mit Thread.Sleep()
?
- Warum sind die Namen der Variablen aktiviert?
- Es. Fixiert es.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ehrlich gesagt, würde ich sagen, dass ich denke, Sie sind ein wenig abseits der ausgetretenen Pfade hier.
Erste von allen, der eigentliche code geschrieben, der nicht wirklich Sinn machen; der worker-thread wartet auf ein signal, aber für keinen Grund - es ist wirklich nicht in eine Schleife irgendeiner Art oder auf eine Ressource warten. Zweitens, wenn Sie es ausführen müssen, einige (vielleicht weggelassen) cleanup-code in der Arbeiter nach Erhalt die shutdown-signal, ist Ihr Dienst möglicherweise nicht die worker-thread-genug Zeit, um aufzuräumen.
Sondern, mehr grundlegend, alles, was Sie getan haben, ist bewegen Sie das problem einen separaten thread. Dies kann halten den service zu reagieren, um den service controller, aber es behebt nicht das problem, und es fügt eine Menge unnötiger Komplexität durch die Verwendung der threads und Mutexe; letztendlich ist es doch nur gehen, um Ihre service schwieriger zu Debuggen, wenn Sie jemals brauchen, um.
Lassen Sie uns sagen, Sie ausführen müssen einige code alle 5 Sekunden. Die Idee ist, statt "warten" 5 Sekunden, invertieren Sie die Kontrolle, und lass den timer aufrufen, Ihre Arbeit.
Das ist schlecht:
Das ist gut:
Das ist es. Das ist alles was Sie tun müssen, um Arbeit zu tun in regelmäßigen Abständen. Solange das Werk selbst nicht läuft, für Sekunden zu einer Zeit, Ihr service bleibt reaktionsschnell Weg zum Dienst-controller. Sie können sogar das anhalten unterstützen, die unter diesem Szenario:
Das einzige mal, wenn Sie brauchen, um zu beginnen, erstellen von worker-threads, die in Ihrem Dienst, wenn Sie die arbeiten selbst ausführen können, für eine sehr lange Zeit, und Sie brauchen die Möglichkeit zum Abbrechen in der Mitte. Das ist eher mit einem guten Angebot design-Aufwand, so dass ich nicht in diese zu bekommen, ohne zu wissen, für sicher, dass es im Zusammenhang zu deinem Szenario.
Es ist am besten, nicht zu starten, die Einführung von Multithreading-Semantik in Ihren Dienst, wenn Sie es wirklich brauchen. Wenn Sie nur versuchen zu planen, kleine-ish Einheiten der Arbeit zu tun, Sie definitiv nicht brauchen.
OnStart
- Methode abgeschlossen ist, wie es ist immer noch ein thread ausgeführt wird, wennOnLoad
endet in einer WinForms -Form
. Nach ausführen derOnStart
code, der service geht in einen message loop, wo es wartet auf Signale von der service controller.Thread.Sleep
Ansatz, aber nicht blockieren den Dienst Steuern. Realistisch betrachtet, wenn das timing ändert sich so drastisch, sollten Sie wahrscheinlich etwas robuster sowieso, also ein job-scheduler und/oder message queue.Thread.Sleep
ist "elegant" in der gleichen Weise wieApplication.DoEvents
ist... also ist es ein hack. Was Sie wirklich für die Modellierung ist ein Ereignis, nicht um eine Schleife, und Sie verschwenden ein thread im Prozess. Sie erhalten auch keine Garantien über die tatsächliche timing;Sleep(x)
bedeutet eigentlich "Schlaf für mindestens "x" - wenn die anderen threads ausgelastet sind, dann wird es vermutlich viel länger. Können Sie sofort mit diesem in ein kleines service? Sicher, genau wie Sie bekommen können Weg mit viel andere schlechte designs in sehr kleine Projekte. Weiß nur, dass es nicht eine gute Praxis.Ich schrieb vor kurzem einen service hatte, um einige Arbeit zu tun, dann warte n Minuten, dann Schleife.
Ich habe auch ein ManualResetEvent (genannt _evt), und ein Aufruf von Set() in OnStop.
Aber ich brauchte nicht einen timer.
In der service-thread, die ich hatte:
Also, entweder ein timeout aufgetreten ist => Zeit für etwas mehr Arbeit. Oder Set() aufgerufen und die Schleife abgebrochen.
WaitOne(n)
?