1

我想知道什麼是最好的方式,以串行處理一個長期運行的進程的結果的低優先級的線程,但在使用.NET 4.0 Parallel Extensions低優先級的線程順序排隊的項目。如何處理使用並行擴展

我有以下類,無論是否執行並提供結果:

public class Step 
{ 
    public string Name { get; set; } 
    public TimeSpan Duration { get; set; } 
    public bool Completed { get; set; } 

    public void Execute() 
    { 
    DateTime before = DateTime.Now; 
    RemotedService.DoSomeStuff(); 
    Duration = DateTime.Now - before; 
    Completed = true; 
    } 
} 

我怎麼可以處理這些步驟,並將它們保存到一個文件,以便他們進行處理後?我想將它們保存到文件中,而RemotedService.DoSomeStuff()正在等待服務器的響應。

寫入文件會是這樣:

想到的是將它們添加到一個 Queue並有 Timer是處理它們
using (StreamWriter w = File.AppendText("myFile.txt")) 
{ 
    var completedStep = completedSteps.Dequeue(); 
    w.WriteLine(string.Format("Completed {0} with result: {1} and duration {2}", 
          completedStep.Name, 
          completedStep.Completed, 
          completedStep.Duration)); 
} 

一個選項。但是這並沒有利用遠程通話的停機時間。

想到的另一個選擇是使用System.Threading.Tasks.Task/Step將每個結果異步寫入文件,但這並不能保證它們將按順序保存,並且還可能引入與文件寫入的爭用。

回答

1

我建議建立一個BlockingCollection<Step>(見System.Collections.Concurrent命名空間)。每完成一個步驟,它都會添加到該集合中。 BlockingCollection的默認行爲是作爲一個隊列,所以你會得到你正在尋找的FIFO行爲。

第二個線程服務隊列,刪除每一個項目,並將其寫入日誌文件。

因此,如果您添加的隊列:

static private BlockingCollection<Step> LogQueue = new BlockingCollection<Step>(); 

您將它添加到您的Execute方法,該項目完成後:

LogQueue.Add(this); 

而且你的記錄線程,你將開始在靜態構造函數中:

static void LoggingThread() 
{ 
    using (var w = new StreamWriter(...)) 
    { 
     while (!LogQueue.IsCompleted()) 
     { 
      Step item; 
      if (LogQueue.TryTake(out item)) 
      { 
       w.WriteLine(....); 
      } 
     } 
    } 
} 

正如我寫的日誌線程使用System.Threading線程。使用TPL可能會有更簡單或更好的方式。我對TPL還不是很熟悉,所以我不能說。

+0

原諒我的無知與線程,但我擔心的是,後臺線程會不必要地處理while循環,當隊列爲空,從而減慢了積極THEAD它實際上做的工作時間。這不是這種情況嗎? – 2010-11-23 11:03:28

+0

換句話說,在後臺線程,LogQueue.IsCompleted()將被並反覆叫過來。我在一個while循環的中間看到了一個Thread.Sleep()來避免這種情況,但我知道這很糟糕。 – 2010-11-23 11:05:37

0

你從字面上描述使用情況Workflow Foundation的 - 它所有的這些東西對你:)

1

一種方法是創建一個自定義任務計劃程序(見http://msdn.microsoft.com/en-us/library/ee789351.aspx)。您的自定義任務調度程序可以將併發性限制爲一次一個,並執行嚴格的按序執行。

創建任務調度程序還允許您控制線程的優先級,或者的ApartmentState這可能是在某些情況下可取的。