我有一個相當複雜的多線程Windows服務工作,但我無法弄清楚如何正確清理。下面是一些[僞]代碼來顯示我的。實際的代碼要複雜得多,在這裏複製/粘貼可能太多了。正確處理線程的類
基本上,我有一個類創建一個線程來完成這項工作的請求。當一個新的請求進入Listener時,它將它發送給處理器,處理器創建新的請求並維護請求列表。如果服務停止,我將清除列表中的所有請求。但是,當請求工作完成後,我該如何清理該類的一個實例?
感謝您的幫助!
尼爾森
class Service
{
Listener listener;
Processor processor;
OnStart()
{
processor = new Processor();
listener = new Listener(processor);
}
OnStop()
{
listener.Dispose();
processor.Dispose();
}
}
class Listener
{
Thread thread;
bool terminate = false;
Listener(Processor processor)
{
thread = new Thread(DoWork);
thread.Start(processor);
}
DoWork(Processor processor)
{
WaitForConnection(NewConnection);
}
NewConnection(String data)
{
processor.NewRequest(data);
if (terminate)
return;
WaitForConnection(NewConnection);
}
Dispose()
{
terminate = true;
thread.Join();
}
}
class Processor
{
//I need to maintain this list so that when the service stops I can cleanly close down
List<Request> requests = new List<Request>();
NewRequest(string data)
{
request.Add(new Request(data));
}
Dispose()
{
//Cleanup each request
foreach (Request request in requests)
{
request.Dispose();
}
}
}
class Request
{
Thread thread;
bool terminate;
Request(string data)
{
while (true)
{
//Do some work
Thread.Sleep(1000);
if (doneWorking)
break;
if (terminate)
return;
}
//We're done. If I return this thread stops. But how do I properly remove this Request instance from the Processor.requests list?
}
Dispose()
{
terminate = true;
thread.Join();
}
}
這基本上是我現在擁有的。感謝您的確認。爲什麼要做requests.ToArray()?是否可以避免鎖定?以任何方式更快/更安全?謝謝。 – 2009-09-22 20:41:45
更安全,性能更好...鎖定是不可能的,因爲其他線程將從我的列表中刪除它,如果我鎖定列表,Join()永遠不會完成。在鎖定期間不要從功能中調出功能是一種最佳做法。此外,我不能簡單地忽略該鎖,因爲該集合將被修改,並且我的foreach循環會得到一個異常。 – 2009-09-22 23:36:30
我在代碼的另一部分獲得了第一手的經驗。我發現這是因爲鎖定()造成的,但是感謝你,我能夠輕鬆解決它。 – 2009-09-28 21:16:40