我是初级程序员,我正在尝试解决任务。使用c#.net 4.0我正在运行文件夹,选择所有* .xml文件,并将每个文件写入具有新扩展名* .bin的新文件夹。对于写入之前的每个文件,我正在应用算法,这是由另一个程序员编写的,我不知道它的实现。
所以我读取* .xml文件,反序列化并将其写入新的* .bin文件。当我没有使用并行编程时,我有2000分钟的文件。现在我决定使用任务来应用并行编程。现在我为每个文件创建新任务(所有进程(read-deserialize-write)都在一个任务中),现在我有40秒。但我认为并行编程帮助我将时间缩短到25-30秒。
请提出你的意见我做错了什么以及如何实现这一点。感谢。
byte[] buffer;
using (Stream stream = new FileInfo(file).OpenRead())
{
buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
}
foreach (var culture in supportedCultures)
{
CultureInfo currentCulture = culture;
Tasks.Add(Task.Factory.StartNew(() =>
{
var memoryStream = new MemoryStream(buffer);
Task<object> serializeTask = Task.Factory.StartNew(() =>
{
return typesManager.Load(memoryStream, currentCulture);
}, TaskCreationOptions.AttachedToParent);
string currentOutputDirectory = null;
if (outputDirectory != null)
{
currentOutputDirectory = outputDirectory.Replace(PlaceForCultureInFolderPath,
currentCulture
.ToString());
Directory.CreateDirectory(currentOutputDirectory);
}
string binFile = Path.ChangeExtension(Path.GetFileName(file), ".bin");
string binPath = Path.Combine(
currentOutputDirectory ?? Path.GetDirectoryName(file),
binFile);
using (FileStream outputStream = File.OpenWrite(binPath))
{
try
{
new BinaryFormatter().Serialize(outputStream,serializeTask.Result);
}
catch (SerializationException e)
{
ReportCompilationError(e.Message, null);
}
}
}));
}
答案 0 :(得分:3)
在没有看到代码或知道任务真正在做什么的情况下,我们所能做的就是提供一些相当一般的建议和诊断。
你的代码是CPU绑定的还是IO绑定的? (您应该能够通过查看性能监视器来了解这一点,并了解运行代码时CPU的繁忙程度。)
如果您的代码是IO绑定的,并且如果您在单个物理非SSD驱动器上有多个文件,那么将工作并行放置可能会使其变得更糟,因为您迫使驱动器头保持不变遍布整个地方。
如果你的代码是CPU绑定的,那么并行化应该正在帮助(因为它们听起来像独立的任务) - 再次,你应该能够通过先运行你的代码而没有并行化然后< em> with 并行化,在两种情况下查看CPU图。您将期望在串行版本中,一次只有一个CPU“忙”,而在并行版本中,所有CPU都应该忙。
答案 1 :(得分:2)
var task1 = Task.Factory.StartNew(() =>
{
//some oepratation
});
var task2 = Task.Factory.StartNew(() =>
{
//some operations
});
Task.WaitAll(task1, task2);
但这并不能保证每个任务都有一个新线程,因为它使用可用的线程,只调度作业或将任务分配给任何可用的线程。因此,我建议你使用Parallel.ForEach
var options = new ParallelOptions { MaxDegreeOfParallelism = 2 // or more };
Parallel.ForEach ( list, options, a=> { } );
http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx
答案 2 :(得分:1)
首先。无法保证TPL会影响性能 正如乔恩所说,写入硬盘可以降低性能,除非操作系统缓存这些文件以供以后顺序写入。绝对缓存大小有其局限性。
二。默认调度程序面向使用CPU内核,因此有可能只有几个任务被并行处理而其他任务在队列中等待。您可以在查询中明确设置ParallelOptions.MaxDegreeOfParallelism
或调用WidthDegreeOfParallelism()
来更改此默认设置。仍然是调度程序决定并行运行多少任务。
在.net
中有一个关于多线程的免费book