Tôi có dịch vụ cửa sổ nhiều luồng trong .Net 3.5 và tôi gặp một số sự cố khi dừng dịch vụ đúng cách khi tạo nhiều hơn một luồng.Dừng dịch vụ cửa sổ nhiều luồng
Dịch vụ này được sử dụng để tạo chỉ một chuỗi để thực hiện tất cả công việc và tôi vừa thay đổi nó thành đa luồng. Nó hoạt động hoàn hảo, nhưng khi dịch vụ được dừng lại, nếu có nhiều hơn một luồng đang được thực thi, nó sẽ treo dịch vụ cho đến khi tất cả các luồng được hoàn tất.
Khi dịch vụ được bắt đầu, tôi tạo ra một sợi nền để xử lý các quá trình chính:
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;
}
Dưới đây là phương pháp 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;
}
Tôi tạo ra một biến tĩnh trong một lớp học riêng biệt để thông báo cho các chủ đề rằng dịch vụ đã bị ngừng. Khi giá trị cho biến này là sự thật, tất cả các chủ đề nên dừng lại vòng lặp chính (một cho mỗi vòng lặp):
public static bool StopService;
Cuối cùng, phương pháp OnStop:
protected override void OnStop()
{
DeliveryConstant.StopService = true;
//flag to tell the worker process to stop
serviceStarted = false;
workerThread.Join(TimeSpan.FromSeconds(30));
}
Trong phương pháp ProcessRequestList, tại cuối mỗi foreach, tôi kiểm tra giá trị của biến StopService. Nếu đúng, tôi phá vỡ vòng lặp.
Đây là vấn đề: Chủ đề được tạo thành các đoạn 50 mục. Khi tôi có 50 mục hoặc ít hơn trong cơ sở dữ liệu, chỉ có một luồng được tạo và mọi thứ đều hoạt động tốt. Khi tôi có hơn 50 mục, nhiều chuỗi sẽ được tạo và khi tôi cố gắng dừng dịch vụ, nó sẽ không dừng cho đến khi tất cả các chủ đề nền được hoàn thành.
Từ nhật ký, tôi có thể thấy rằng phương thức OnStop chỉ được thực thi SAU KHI tất cả các chuỗi được hoàn tất.
Bất kỳ đầu mối nào có thể được thay đổi để sửa lỗi đó?
Thử đặt chế độ Ngủ (50) trong vòng lặp while. –
Dường như với tôi rằng Bạn chưa bao gồm phần quan trọng nhất của mã. Đó là thực thi phương thức ProcessRequestList. –
Bạn có thể hiển thị mã nơi StopService được thẩm vấn không? Nhìn vào bằng cách sử dụng CancellationToken trên tĩnh var, vì nó được làm cho loại điều đó. – hatchet