2

I'm working on a copy app that can copy multiple directories. In a JSonFile I've got datas about the name of the directory, its source path, destination path (for the copy), size, files extensions... etc. The app reads the file then uses the data stored in it to perform the copy. If I wanted to perform a lot of copies at one time, the app used to copy them sequentially (1st copy task-> 2nd copy task -> 3rd copy task) but now I want to do them all simultaneously so I've created this method:

 public void parallelCopy(string st1)
    {
        DirectoryInfo logPath = new DirectoryInfo(@"C:\Users\usr01\source\repos\CopyProg\LogFiles\tmpLog");
        FileInfo[] logList = logPath.GetFiles();

        foreach (FileInfo file in logList)
        {
            string JSonFile = File.ReadAllText(@"C:\Users\usr01\source\repos\CopyProg\LogFiles\tmpLog" + file.Name);
            JSonFile = JSonFile.Replace("][", ",");
            dynamic objects = JsonConvert.DeserializeObject<dynamic>(JSonFile);
            Task t;
            foreach (var element in objects)
            {
                DirectoryInfo dirSrcPath = new DirectoryInfo((string)element.SourcePath);
                DirectoryInfo dirDstPath = new DirectoryInfo((string)element.DestinationPath);

                if (element.copyType == "1")
                {
                    watch1.Start();
                    t = Task.Factory.StartNew(() => mirrorCopy((string)element.SourcePath, (string)element.DestinationPath, false));
                    Task.WaitAny(t);
                    tskLst.Add(t);
                    time1 = watch1.Elapsed;
                    watch1.Stop();
                    jsTrt1.writeLogs((string)element.Name, dirSrcPath, dirDstPath, "1", DirSize(dirSrcPath), DateTime.Now, time1);
                }
                else if(element.copyType == "2")
                {
                    watch1.Start();
                    t = Task.Factory.StartNew(() => differentialCopy(dirSrcPath, dirDstPath, false));
                    Task.WaitAny(t);
                    tskLst.Add(t);
                    time1 = watch1.Elapsed;
                    watch1.Stop();
                    jsTrt1.writeLogs((string)element.Name, dirSrcPath, dirDstPath, "1", DirSize(dirSrcPath), DateTime.Now, time1);
                }
            }
        }
        for (int i = 0; i < tskLst.Count; i++)
        {
            Thread.Yield();
        }
    }

It seems to be working just fine even tho I'm pretty sure that's not how am i supposed to do it. I want to set a priority system, something like directories with files having a ".docx" or a ".mp3" extensions should be copied first. And if the size of directory is too big, he'll be the last one to get copied. Any ideas on how I can do it?

VillageTech
  • 1,968
  • 8
  • 18
  • Why not calculating the available size, then decide which files can go into this? Setting a priority if everything starts at the same time is impossible. – Athanasios Kataras Dec 13 '19 at 16:39
  • You could switch to a parallel foreach to speed up the process. If you're on a multi core processor you could see a marked improvement. https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel.foreach?view=netframework-4.8 – B Minster Dec 13 '19 at 22:00
  • OP, have you tried a version of this code without the parallel tasks? It might perform just as well or even faster. Parallel processing can speed things up for CPU-bound tasks, but these would appear to be I/O-bound. See [parallel execution for IO bound operations](https://stackoverflow.com/questions/35686341/parallel-execution-for-io-bound-operations). If the copy operations are performed in series then it is trivial to prioritize them. – John Wu Dec 13 '19 at 23:25
  • Parallel.ForEach with the MaxDegreeOfParallelism param? – Ross Bush Dec 14 '19 at 03:10

0 Answers0