我在.Net 3.5中有一個多線程的Windows服務,並且在創建多個線程時我有一些麻煩來正確地停止該服務。停止多線程的Windows服務
此服務用於創建只有一個線程來完成所有的工作,我只是將其更改爲多線程。它完美地工作,但是當服務停止時,如果多個線程正在執行,它將掛起服務,直到所有線程完成。
當該服務啓動後,我創建了一個後臺線程來處理的主要過程:
protected override void OnStart(string[] args)
{
try
{
//Global variable that is checked by threads to learn if service was stopped
DeliveryConstant.StopService = false;
bool SetMaxThreadsResult = ThreadPool.SetMaxThreads(10, 10);
ThreadStart st = new ThreadStart(StartThreadPool);
workerThread = new Thread(st);
workerThread.IsBackground = true;
serviceStarted = true;
workerThread.Start();
}
catch (Exception ex)
{
//Log something;
}
這裏是StartThreadPool方法:
//Tried with and without this attribute with no success...
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
public void StartThreadPool()
{
while (serviceStarted)
{
ProcessInfo input = new ProcessInfo();
try
{
int? NumPendingRequests = GetItems(50, (Guid?)input.ProcessID);
if (NumPendingRequests > 0)
{
input.ProcessType = 1;
input.ProcessID = Guid.NewGuid();
ThreadPool.QueueUserWorkItem(new WaitCallback(new DispatchManager().ProcessRequestList), input);
}
}
catch (Exception ex)
{
//Some Logging here
}
}
DeliveryConstant.StopService = true;
}
我在單獨的類中創建一個靜態變量通知線程服務已停止。當此變量的值爲true,所有線程應該停止主循環(每個循環):
public static bool StopService;
最後,調用OnStop方法:
protected override void OnStop()
{
DeliveryConstant.StopService = true;
//flag to tell the worker process to stop
serviceStarted = false;
workerThread.Join(TimeSpan.FromSeconds(30));
}
在ProcessRequestList方法中,在每個foreach的結尾,我檢查StopService變量的值。如果這是真的,我打破循環。
這裏的問題是: 的線程中的50項塊創建。當我在數據庫中有50個或更少的項目時,只創建一個線程,並且一切都很好。 當我有超過50個項目時,將創建多個線程,並且當我嘗試停止服務時,它不會停止,直到完成所有後臺線程。
從日誌中,我可以看到方法OnStop只在所有線程完成後執行。
任何線索可以改變什麼來解決這個問題?
嘗試在while循環中放置睡眠(50)。 –
在我看來,你沒有包含代碼的最重要部分。這是ProcessRequestList方法的實現。 –
你可以顯示StopService被詢問的代碼嗎?查看使用CancellationToken通過靜態var,因爲它是爲這樣的事情。 – hatchet