我在 .Net 3.5 中有一个多线程 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;
}
我在一个单独的类中创建了一个静态变量来通知线程该服务已停止。当这个变量的值为真时,所有线程都应该停止主循环(每个循环一个):
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 方法仅在所有线程完成后执行。
任何线索可以改变什么来解决这个问题?