如何优化我的并行执行函数

本文关键字:我的 并行执行 函数 优化 何优化 | 更新日期: 2023-09-27 17:56:34

我一直在阅读很多关于并行.net 4的信息,我不得不说我有点困惑何时使用它。

这是我的常见场景我被赋予了一项将大量 xml 文件迁移到数据库的任务。

通常我必须

  1. 读取 Xml 文件 (100.000) 等,并按数字排序(每个文件命名为 1.xml、2.xml 等)。
  2. 保存到数据库。

我认为以上是并行编程的完美候选者。

从概念上讲,我想一次处理许多文件。

我目前正在这样做:

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使用并行是加快这些文件处理速度的最佳/更简单的方法吗?上面的 psudo 代码是否足够好,或者我是否缺少重要的东西,锁定等......

最重要的问题是:忘记"进程文件",因为我无法优化,因为我无法控制 是否有优化的余地

我应该将文件分成块,例如 1-1000 - 1001-2000-2001-3000 会提高性能吗(你怎么做)

非常感谢任何回复或链接/代码片段,可以帮助我更好地了解如何改进上述代码。

如何优化我的并行执行函数

你没有收到回复的原因是因为你的代码大错特错了。AsParallel() 不对 GetFiles() 文件执行任何操作。Count() 实际上迭代了枚举,因此不仅您读取文件(或只是目录)两次,而且先执行 Count(),然后再遍历它们将读取文件两次,如果目录被修改,可能会产生不一致的计数。看起来没有必要执行 Task.Factory.StartNew,因为它是您唯一的任务(它会在其中生成并行处理)。Parallel.ForEach 会将所有 OperationCancelException 封装到单个 AggregateException 中,但它只会在所有并行线程完成其工作后执行此操作。

我保留了代码,因为没有人为我提供合适的答案