如何使用并行扩展串行处理的低优先级的线程排队项目
-
27-09-2019 - |
题
我想知道什么是最好的方式,以串行处理一个长期运行的进程的结果,但在使用的。NET 4.0并行扩展的。
我有以下的类,这两个不执行,并提供其结果:
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()
正在等待来自服务器的响应。
写入文件会是这样:
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));
}
,想到一个办法就是将它们添加到Queue
并有Timer
是处理它们。但是,这并不采取远程的电话的停机时间的优势。
想到的另一种选择是异步写入每个结果使用每一个System.Threading.Tasks.Task
的Step
文件,但这并不能保证他们将被保存,以便并且还可能与写入文件引入竞争。
解决方案
我建议创建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,所以我不能说。
其他提示
的一种方法是创建一个定制任务计划(见 HTTP:// MSDN .microsoft.com / EN-US /库/ ee789351.aspx )。自定义任务调度器可以限制并发到一个在-A-时间和执行严格的顺序执行。
创建任务调度器还允许您控制线程优先级,或的ApartmentState这可能是在某些情况下期望的。
您从字面上描述使用情况Workflow Foundation的 - 它所有的这些东西给你:)