1

I'm encountering a problem I don't seem to quite understand.

I have this code I found Here which I tried to modify to my needs:

Folder objFolder;
LoadHeader(path, out arrHeaders, out objFolder);
foreach (Shell32.FolderItem2 item in objFolder.Items())
{ 
            List<DateTime> tmp = new List<DateTime>();
            DateTime SelectedDate;
            foreach (int h in date)
            {
                string l = objFolder.GetDetailsOf(item, h);
                if (!string.IsNullOrEmpty(l))
                {
                    string asAscii = Encoding.ASCII.GetString(
                        Encoding.Convert(
                            Encoding.UTF8,
                            Encoding.GetEncoding(
                                Encoding.ASCII.EncodingName,
                                new EncoderReplacementFallback(string.Empty),
                                new DecoderExceptionFallback()),
                            Encoding.UTF8.GetBytes(l)
                            ));
                    tmp.Add(DateTime.Parse(asAscii.Substring(0, 11)));
                }
            }
            if (tmp.Count == 0)
                SelectedDate = File.GetCreationTime(item.Path);
            else
                SelectedDate = tmp.Min();
            FileToSort.Add(new FileToSort(item.Name, item.Path, SelectedDate));
        }
}

The problem appeared when I tried to speed up the foreach using the Parallel.ForEach() since it get strangely slow when confronted with a large number of file

 Folder objFolder;
 LoadHeader(path, out arrHeaders, out objFolder);
 Parallel.ForEach(/*(IEnumerable<FolderItem2>)*/objFolder.Items(),
 (Shell32.FolderItem2 item) =>
 {
  /*Some work*/
 });

This code even with the suggested Visual Studio cast throws an exception of type System.InvalidCastException

Cannot cast object of type System.__ComObject to interface type System.Collections.Generic.IEnumerable`1[Shell32.FolderItem2]

So what I'm wondering is what the 2 foreach differentiate from each other, and if I can replicate the classic foreach behavior to use the parallel one, or is it something that can't be done?

Armach
  • 15
  • 1
  • 5
  • 2
    Can't be done, that interface is not thread-safe. You could iterate it to create a `List` and parallelize over that list. Do keep in mind that file operations in general are not sped up by threads and can in fact get significantly slower. – Hans Passant May 30 '22 at 22:44
  • 1
    Assuming it is a thread safety problem, setting an attribute `Main()` of `[STAThread]` should fix that, but then it will obviate any possible gain from multi-threading in the first place. Is there any reason you are not using `FileInfo` anyway? – Charlieface May 31 '22 at 00:25
  • Thank all, the problem is I can't use or I didn't use `FileInfo` cause I didn't find a code to easily read the Extended property of the file, this program is taking all the Date I was able to identify inside the extended property and then choosing the "right" one I didn't ask the specific question about the extended property since there is already some good answer but they mostly use this Shell32 object I'm just unaware on how to parallelize the file reading procedure – Armach May 31 '22 at 10:09

0 Answers0