我已经阅读了很多关于 Parallel .net 4 的内容,我不得不说我有点困惑何时使用它。
这是我的常见场景,我被赋予了将大量 xml 文件迁移到数据库的任务。
我通常必须
- 阅读 Xml 文件 (100.000) 和更多文件并按数字顺序排列它们(每个文件命名为 1.xml、2.xml 等)。
- 保存到数据库。
我认为上面是并行编程的完美候选者。
从概念上讲,我想一次处理许多文件。
我目前正在这样做:
private ResultEventArgs progressResults=new ResultEventArgs();
public void ExecuteInParallelTest()
{
var sw=new Stopwatch();
sw.Start();
int index = 0;
cancelToken = new CancellationTokenSource();
var parOpts = new ParallelOptions();
parOpts.CancellationToken = cancelToken.Token;
parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; //It this correct?
FileInfo[] files = myDirectory.EnumerateFiles("*.xml").ToArray();//Is this faster?
TotalFiles = files.Count();
try
{
Task t1 = Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(files, parOpts, (file, loopState) =>
{
if (cancelToken.Token.IsCancellationRequested)
{
cancelToken.Token.ThrowIfCancellationRequested();
}
index = Interlocked.Increment(ref index);
ProcessFile(file,index);
progressResults.Status=InProgress
OnItemProcessed(TotalFiles,index,etc..);
});
}
catch (OperationCanceledException ex)
{
OnOperationCancelled(new progressResults
{
progressResults.Status=InProgress
progressResults.TotalCount = TotalFiles;
progressResults.FileProcessed= index;
//etc..
});
}
//ContinueWith is used to sync the UI when task completed.
}, cancelToken.Token).ContinueWith((result) => OnOperationCompleted(new ProcessResultEventArgs
{
progressResults.Status=InProgress
progressResults.TotalCount = TotalFiles;
progressResults.FileProcessed= index;
//etc..
}), new CancellationTokenSource().Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (AggregateException ae)
{
//TODO:
}
}
我的问题:我正在使用 .net 4.0 使用 Parallel 是加快处理这些文件的最佳/更简单的方法。上面的伪代码是否足够好,或者我错过了重要的东西,锁定等......
最重要的问题是:忘记“ProcessFile”,因为我无法对其进行优化,因为我无法控制是否有优化空间
我是否应该将文件分成块,例如 1-1000 - 1001-2000-2001-3000 会提高性能(你是如何做到的)
非常感谢任何可以帮助我更好地理解如何改进上述代码的回复或链接/代码片段。