[英]Properly disposing of class with thread
我有一個相當復雜的多線程Windows服務工作,但我無法弄清楚如何正確清理。 下面是一些顯示我擁有的[偽]代碼。 實際的代碼要復雜得多,可能要復制/粘貼太多。
基本上,我有一個類Request創建一個線程來完成工作。 當一個新請求進入監聽器時,它會將它發送到處理器,處理器創建新的請求並維護請求列表。 如果服務停止,我清理列表中的所有請求。 但是當Request工作完成后,我該如何清理該類的一個實例?
謝謝你的幫助!
納爾遜
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();
}
}
一種可能性是以委托的形式將回調傳遞給請求:“當你完成處理后,給我回電話告訴我”。 然后在請求處理結束時執行回調並讓它處理清理。
但需要注意的一件事是:如果你試圖通過你的列表處理事物,然后嘗試從另一個線程的列表中刪除一個項目,你就會遇到問題。 你應該保留一個標志(以線程安全的方式訪問),一旦你開始處理列表中的所有內容,忽略你得到的任何回調。
這是一個粗略的草圖:
delegate void CompletedRequest(Request req);
class Processor : ITrackCompletion
{
//I need to maintain this list so that when the service stops I can cleanly close down
List<Request> requests = new List<Request>();
public void NewRequest(string data)
{
lock(requests)
request.Add(new Request(data), Complete);
}
public void Complete(Request req)
{
lock (requests)
requests.Remove(req);
}
public void Dispose()
{
//Cleanup each request
foreach (Request request in requests.ToArray())
{
request.Dispose();
}
}
}
class Request
{
Thread thread;
bool terminate;
public Request(string data, CompletedRequest complete)
{
try
{
while (true)
{
//Do some work
Thread.Sleep(1000);
if (doneWorking)
break;
if (terminate)
return;
}
}
finally
{
//We're done. If I return this thread stops. But how do I properly remove this Request instance from the Processor.requests list?
complete(this);
}
}
void Dispose()
{
terminate = true;
thread.Join();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.