如何使用并行扩展在低优先级线程上串行处理排队项目
我想知道使用 .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));
}
我想到的一个选项是将它们添加到队列中,并让一个计时器来处理它们。但这并没有利用远程调用的停机时间。
我想到的另一个选择是使用每个 Step
使用 System.Threading.Tasks.Task 将每个结果异步写入文件,但这并不能保证它们会按顺序保存,并且还可能引入写入文件的争用。
I want to know what the best way to process the results of a long-running process serially but on a low-priority thread using the .NET 4.0 Parallel Extensions.
I have the following class that both does the execution and provides the results:
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;
}
}
How can I process these steps and also save them to a file, in order, after they are processed? I would like to save them to a file while RemotedService.DoSomeStuff()
is waiting for a response from the server.
Writing to the file would be like this:
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));
}
One option that comes to mind is to add them to a Queue
and have a Timer
that processes them. But this doesn't take advantage of the downtime of the remoted calls.
Another option that comes to mind is to asynchronously write each result to the file using a System.Threading.Tasks.Task
per Step
, but that doesn't guarantee that they will be saved in order and may also introduce contention with writing to the file.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议创建一个
BlockingCollection
(请参阅System.Collections.Concurrent
命名空间)。每个步骤完成后,都会将其添加到该集合中。BlockingCollection
的默认行为是充当队列,因此您将获得所需的 FIFO 行为。第二个线程为队列提供服务,删除每个项目并将其写入日志文件。
因此,如果您添加了队列:
您将在项目完成后将其添加到您的 Execute 方法中:
以及您的日志记录线程,您将在静态构造函数中启动
该日志记录线程 :我已经写过它使用 System.Threading 线程。使用 TPL 可能有一种更简单或更好的方法。我对 TPL 还不是很熟悉,所以我不能说。
I would suggest creating a
BlockingCollection<Step>
(seeSystem.Collections.Concurrent
namespace). As each step is completed, it's added to that collection. The default behavior ofBlockingCollection
is to function as a queue, so you'll get the FIFO behavior you're looking for.A second thread services the queue, removing each item and writing it to a log file.
So, if you added the queue:
You would add this to your
Execute
method, after the item is completed:And your logging thread, which you would start in the static constructor:
The logging thread as I've written it uses a
System.Threading
thread. There might be an easier or better way to do it with TPL. I'm not yet terribly familiar with TPL, so I couldn't say.一种方法是创建自定义任务计划程序(请参阅 http://msdn.microsoft. com/en-us/library/ee789351.aspx)。您的自定义任务计划程序可以将并发限制为一次一个,并强制执行严格的按顺序执行。
创建任务调度程序还允许您控制线程优先级,或在某些情况下可能需要的 ApartmentState。
One approach is to create a custom Task Scheduler (see http://msdn.microsoft.com/en-us/library/ee789351.aspx). Your custom task scheduler can limit concurrency to one-at-a-time and enforce strict in-order execution.
Creating a task scheduler also allows you to control the thread priority, or the ApartmentState which may be desirable in some situations.
您实际上是在描述 Workflow Foundation 的用例 - 它为您完成所有这些工作:)
You're literally describing the use case for Workflow Foundation - it does all of this stuff for you :)