Yanıtlar:
Güncelleme:
İlk cevabımdan yaklaşık dört yıl sonra ve bu cevap çok güncel değil. TopShelf ortaya çıktığından beri Windows Hizmetlerinin geliştirilmesi kolaylaştı. Şimdi sadece yük devretmeyi nasıl destekleyeceğinizi bulmanız gerekiyor ...
Orijinal Cevap:
Gerçekten Windows Zamanlayıcı hayranı değilim. Kullanıcı şifresi, yukarıda belirtildiği gibi @moodforall'un belirttiği şekilde sağlanmalıdır , bu, birisi bu kullanıcının şifresini değiştirdiğinde eğlencelidir.
Windows Zamanlayıcı ile ilgili diğer büyük sıkıntı, arka plan işlemi olarak değil etkileşimli olarak çalışmasıdır. Bir RDP oturumu sırasında her 20 dakikada bir 15 MS-DOS penceresi açıldığında, bunları Windows Hizmetleri olarak yüklemeyen kendinizi atarsınız.
Neyi seçerseniz seçin, işleme kodunuzu konsol uygulamasından veya Windows Hizmetinden farklı bir bileşene ayırmanızı kesinlikle tavsiye ederim. Ardından, çalışan işlemi bir konsol uygulamasından çağırıp Windows Zamanlayıcı'ya bağlama veya bir Windows Hizmeti kullanma seçeneğiniz vardır.
Bir Windows Hizmeti planlamanın eğlenceli olmadığını göreceksiniz. Oldukça yaygın bir senaryo, periyodik olarak çalıştırmak istediğiniz uzun süren bir işleminizin olmasıdır. Ancak, bir kuyruğu işliyorsanız, aynı çalışanın iki örneğinin aynı kuyruğu işlemesini gerçekten istemezsiniz. Bu nedenle, uzun süren işleminizin atanan zamanlayıcı aralığından daha uzun çalışıp çalışmadığından emin olmak için zamanlayıcıyı yönetmeniz gerekir, mevcut işlem bitene kadar tekrar başlamaz.
Tüm bunları yazdıktan sonra, neden Thread.Sleep kullanmadım diye düşünüyorsun? Bu, mevcut iş parçacığının bitene kadar çalışmaya devam etmesine izin vermeme izin veriyor ve ardından duraklama aralığı devreye giriyor, iş parçacığı uykuya geçiyor ve gerekli süreden sonra tekrar başlıyor. Temiz!
Daha sonra internetteki tüm tavsiyeleri okuyup, programlamanın gerçekten kötü olduğunu söyleyen bir sürü uzmanla:
Yani kafanı kaşıyacak ve kendi kendine düşüneceksin, WTF, Bekleyen Kontrolleri Geri Al -> Evet, eminim -> Bugünün tüm işlerini geri al ..... kahretsin, kahretsin, kahretsin ....
Bununla birlikte, herkes bunun saçmalık olduğunu düşünse bile, bu kalıbı seviyorum:
Tek iş parçacığı yaklaşımı için OnStart yöntemi.
protected override void OnStart (string args) { // Create worker thread; this will invoke the WorkerFunction // when we start it. // Since we use a separate worker thread, the main service // thread will return quickly, telling Windows that service has started ThreadStart st = new ThreadStart(WorkerFunction); workerThread = new Thread(st); // set flag to indicate worker thread is active serviceStarted = true; // start the thread workerThread.Start(); }
Kod, ayrı bir iş parçacığı oluşturur ve ona işçi işlevimizi ekler. Ardından iş parçacığını başlatır ve OnStart olayının tamamlanmasını sağlar, böylece Windows hizmetin askıda olduğunu düşünmez.
Tek iş parçacığı yaklaşımı için çalışan yöntem.
/// <summary> /// This function will do all the work /// Once it is done with its tasks, it will be suspended for some time; /// it will continue to repeat this until the service is stopped /// </summary> private void WorkerFunction() { // start an endless loop; loop will abort only when "serviceStarted" // flag = false while (serviceStarted) { // do something // exception handling omitted here for simplicity EventLog.WriteEntry("Service working", System.Diagnostics.EventLogEntryType.Information); // yield if (serviceStarted) { Thread.Sleep(new TimeSpan(0, interval, 0)); } } // time to end the thread Thread.CurrentThread.Abort(); }
Tek iş parçacığı yaklaşımı için OnStop yöntemi.
protected override void OnStop() { // flag to tell the worker process to stop serviceStarted = false; // give it a little time to finish any pending work workerThread.Join(new TimeSpan(0,2,0)); }
Kaynak: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)
Yıllardır bunun gibi birçok Windows Hizmeti çalıştırıyorum ve benim için çalışıyor. Hala insanların hemfikir olduğu önerilen bir model görmedim. Sadece sizin için uygun olanı yapın.
NT AUTHORITY\NetworkService
Sınırlı ayrıcalıklara sahip bir hesaptır.
Burada bazı yanlış bilgiler. Windows Zamanlayıcı, görevleri arka planda pencereler açılmadan ve parola gerektirmeden mükemmel şekilde çalıştırabilir. NT AUTHORITY \ SYSTEM hesabı altında çalıştırın. Bu schtasks anahtarını kullanın:
/ ru SİSTEMİ
Ancak evet, ağ kaynaklarına erişmek için en iyi uygulama, ayrı bir süresi dolmayan parola politikasına sahip bir hizmet hesabıdır.
DÜZENLE
İşletim sisteminize ve görevin gereksinimlerine bağlı olarak, /ru
seçenekle birlikte Localsystem'den daha az ayrıcalıklı hesapları kullanabilirsiniz .
İnce kılavuzdan ,
/RU username
A value that specifies the user context under which the task runs.
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM".
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and
"NT AUTHORITY\NETWORKSERVICE" are also valid values.
Görev Zamanlayıcı 2.0 , Vista ve Server 2008'de mevcuttur.
XP ve Server 2003'te system
tek seçenektir.
Local Service
(aka NT AUTHORITY\LocalService
yerine) LocalSystem
(aka .\LocalSystem
). İlki sınırlı haklara sahipken, ikincisi bir yönetici
LocalService
ve NetworkService
mevcuttur schtasks
itibaren Vista v2 ve mümkün olduğunca tercih edilmelidir. O zamanlar, bu, schtasks
yalnızca System
eski sürüm kılavuzuna göre parametre olarak kabul eden XP ve Server 2003'e atıfta bulundu technet.microsoft.com/en-us/library/bb490996.aspx
Uygulamayı başlatmanın ve uygulamadan çıkmanın ek yükü nedir? Her iki dakikada bir oldukça sık. Bir hizmet muhtemelen sistemin uygulamanızı çok sık çalıştırmaya göre daha sorunsuz çalışmasına izin verir.
Her iki çözüm de kullanıcı oturum açmadığında programı çalıştırabilir, dolayısıyla hiçbir fark yoktur. Bir hizmet yazmak, normal bir masaüstü uygulamasından biraz daha karmaşık olsa da, hizmet uygulamasıyla TCP / IP, adlandırılmış kanallar vb. Aracılığıyla iletişim kuracak ayrı bir GUI istemcisine ihtiyacınız olabilir.
Bir kullanıcının bakış açısıyla, hangisinin daha kolay kontrol edilebileceğini merak ediyorum. Hem hizmetler hem de zamanlanmış görevler, teknik olmayan çoğu kullanıcı için hemen hemen erişilemez, yani var olduklarını fark etmezler ve yapılandırılabilir / durdurulabilir / yeniden planlanabilir vb.
.NET geliştirmede, normal olarak bir Konsol Uygulaması geliştirerek işe başlarım, tüm günlük çıktılarını konsol penceresine çalıştıracak. Ancak, bu yalnızca komut bağımsız değişkeniyle çalıştırıldığında bir Konsol Uygulamasıdır /console
. Bu parametre olmadan çalıştırıldığında, kendi özel kodlanmış zamanlanmış zamanlayıcımda çalışmaya devam edecek bir Windows Hizmeti gibi davranır.
Bana kalırsa Windows Hizmetleri, uzun süre çalışan bir uygulama olmaktan ziyade diğer uygulamaları yönetmek için kullanılır. VEYA .. sürekli olarak SQL Server, BizTalk, RPC Bağlantıları, IIS gibi ağır uygulamaları çalıştırırlar (IIS teknik olarak yükleri diğer işlemlere aktarmasına rağmen).
Kişisel olarak, tekrarlayan bakım görevleri ve dosya kopyalama / senkronizasyon, toplu e-posta gönderme, dosyaların silinmesi veya arşivlenmesi, veri düzeltme (diğer geçici çözümler mevcut olmadığında) gibi uygulamalar için Windows Hizmetleri yerine zamanlanmış görevleri tercih ediyorum.
Bir proje için 8 veya 9 Windows Hizmetinin geliştirilmesine dahil oldum, ancak bunlar bellekte oturuyor, boşta, örnek başına 20MB veya daha fazla bellek tüketiyorlar. Zamanlanmış görevler kendi işlerini yapacak ve belleği hemen serbest bırakacaktır.
"Hizmet" kelimesi "hizmetçi" ile ortak bir şeyi paylaşır. Her zaman çalışıyor olması ve 'hizmet' olması bekleniyor. Görev, görevdir.
Rol yapma. Başka bir işletim sistemi, uygulama veya cihaz isem ve bir servisi ararsam, onun çalışıyor olmasını bekliyorum ve bir yanıt bekliyorum. Eğer (os, uygulama, dev) sadece izole bir görevi yürütmem gerekiyorsa, o zaman bir görevi yürüteceğim, ancak iletişim kurmayı bekliyorsam, muhtemelen iki yönlü iletişim, bir hizmet istiyorum. Bunun, iki şeyin iletişim kurması için en etkili yolla veya tek bir görevi yerine getirmek isteyen tek bir şeyle ilgisi var.
Sonra zamanlama yönü var. Bir şeyin belirli bir zamanda çalışmasını istiyorsanız, programlayın. Ne zaman ihtiyacınız olacağını bilmiyorsanız veya "anında" ihtiyacınız varsa, hizmet.
Cevabım doğası gereği daha felsefi çünkü bu, insanların başkalarıyla nasıl etkileşime girip çalıştığına çok benziyor. İletişim sanatını ne kadar anlarsak ve "varlıklar" rollerini anladıkça, bu karar daha kolay hale gelir.
Tüm felsefe bir yana, BT Departmanımın sık sık yaptığı gibi, "hızlı prototipleme" yaptığınızda, geçiminizi sağlamak için ne gerekiyorsa yaparsınız. Kavram malzemelerinin prototipi ve kanıtı yoldan çıktığında, genellikle erken planlama ve keşfetmede, uzun vadeli sürdürülebilirlik için neyin daha güvenilir olduğuna karar vermelisiniz.
Tamam, sonuç olarak, birçok faktöre büyük ölçüde bağlı, ancak umarım bu kafa karışıklığı yerine fikir sağladı.
Bir Windows hizmetinin hiç kimsenin oturum açmasına gerek yoktur ve Windows, hizmet sonuçlarını durdurmak, başlatmak ve günlüğe kaydetmek için olanaklara sahiptir.
Zamanlanmış bir görev, bir Windows hizmetinin nasıl yazılacağını öğrenmenizi gerektirmez.
NT AUTHORITY\LocalService
, veya NT AUTHORITY\NetworkService
). Verilen herhangi bir şifre, hesapların şifresi olmadığı için dikkate alınmaz.
Neden ikisini birden sağlamıyorsunuz?
Geçmişte 'çekirdek' bitleri bir kitaplığa koydum ve hem bir hizmette hem de bir konsol uygulamasında Whatever.GoGoGo () için bir çağrı yaptım.
Her iki dakikada bir ateşlediğiniz bir şeyle, olasılıklar makul, fazla bir şey yapmıyor (örneğin, sadece "ping" tipi bir fonksiyon). Sarmalayıcıların tek bir yöntem çağrısından ve bazı günlük kayıtlarından fazlasını içermesi gerekmez.
Bu eski bir soru ama karşılaştıklarımı paylaşmak isterim.
Son zamanlarda bir radarın ekran görüntüsünü (Meteoroloji web sitesinden) yakalama ve her 10 dakikada bir sunucuya kaydetme zorunluluğu getirildi.
Bu, WebBrowser kullanmamı gerektirdi. Genellikle Windows hizmetleri yapıyorum, bu yüzden bunu da yapmaya karar verdim ama çökmeye devam edecek. Olay Görüntüleyicisi Hatalı modül yolunda gördüğüm şey bu : C: \ Windows \ system32 \ MSHTML.dll
Görev acil olduğu ve araştırma ve deney yapmak için çok az zamanım olduğu için basit bir konsol uygulaması kullanmaya karar verdim ve bir görev olarak tetikledim ve sorunsuz bir şekilde yürütüldü.
Mark Ransom tarafından kabul edilen cevapta Jon Galloway tarafından önerilen makaleyi gerçekten beğendim .
Son zamanlarda sunuculardaki şifreler beni onaylamadan değiştirildi ve oturum açamadıkları için tüm hizmetler yürütülemedi. Bu yüzden makalesinde bunun bir sorun olduğunu iddia eden ppl. Windows hizmetlerinin de aynı sorunla karşılaşabileceğini düşünüyorum (Pls. Yanılıyorsam beni düzelt, ben sadece bir acemiyim)
Ayrıca belirtilen şey, görev zamanlayıcı pencereleri açılırsa veya konsol penceresi açılırsa. Ben bununla hiç yüzleşmedim. Açılabilir ama en azından çok anlıktır.
Genel olarak, temel mesaj, kodun her bir "tetikleyici / istemciden" çalıştırılabilir olması gerektiğidir ve böyle olmalıdır. Dolayısıyla bir yaklaşımdan diğerine geçmek roket bilimi olmamalıdır.
Geçmişte her zaman Windows Hizmetlerini az çok kullandık, ancak aynı zamanda giderek daha fazla müşterimiz Azure'a adım adım geçtiğinden ve bir Konsol Uygulamasından (Zamanlanmış Görev olarak dağıtılır) Azure'da bir WebJob'a geçiş yapmaktan çok daha kolaydır. bir Windows Hizmeti, şimdilik Zamanlanmış Görevlere odaklanıyoruz. Sınırlamalarla karşılaşırsak, Windows Hizmeti projesini hızlandırır ve oradan aynı mantığı çağırırız (müşteriler OnPrem'de çalıştığı sürece ..) :)
BR, y
Windows hizmetleri, tamamlanana kadar daha fazla sabır ister. Biraz zor hata ayıklama ve yükleme var. Yüzsüz. Her saniye, dakika veya saatte bir yapılması gereken bir göreve ihtiyacınız varsa, Windows Hizmetini seçmelisiniz.
Zamanlanmış Görev hızla geliştirilir ve bir yüzü vardır. Günlük veya haftalık bir göreve ihtiyacınız varsa, Zamanlanmış Görevi kullanabilirsiniz.