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这可能是在某些情况下可取的。