簡體   English   中英

正確處理帶線程的類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM