When the Parallel.ForEach loop iterates over a large pickedFiles collection with a big number of files ~300 than my application fail with System.OutOfMemoryException. When the files number is small everything is ok. This error happens only in x86 compile mode, in x64 compile mode application won't fall.
Total size of files is 55Gb. Some file few kb large others can be up to 20 GB.
How to fix this error? I really need to use Parallel.ForEach because the speed is much faster than in an ordinary loop, but I can't figure out why this error occurs. The application memory usage doesn't exceed 900 MB in x-86 debug mode when I analyze in performance profiler.
Here is my UWP solution 1drv.ms/u/s!AmDz4cAaOTuzgzAsuSt3P6v9ouCF?e=qVkJeI
public sealed partial class MainPage : Page
{
FileOpenPicker picker { get; set; }
IReadOnlyList<StorageFile> pickedFiles { get; set; }
const int chunkSize = 10000000;
public MainPage()
{
this.InitializeComponent();
}
async public void F1()
{
ParallelOptions parallelOptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(pickedFiles, parallelOptions,async(file) =>
{
StorageFile createdFile = await createEmptyFileAsync(file);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
ulong remainingSize = stream.Size;
ulong startPosition = 0;
while (remainingSize > 0)
{
using (DataReader reader = new DataReader(stream.GetInputStreamAt(startPosition)))
{
if (chunkSize >= remainingSize)
{
byte[] buffer = new byte[remainingSize];
await reader.LoadAsync((uint)remainingSize);
reader.ReadBytes(buffer);
await writeTo(createdFile, buffer);
remainingSize = 0;
}
else
{
byte[] buffer = new byte[chunkSize];
await reader.LoadAsync(chunkSize);
reader.ReadBytes(buffer);
await writeTo(createdFile, buffer);
startPosition += chunkSize;
remainingSize -= chunkSize;
}
}
}
}
});
{
}
}
async void GetFile(object sender, RoutedEventArgs e)
{
picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
picker.FileTypeFilter.Add("*");
pickedFiles = await picker.PickMultipleFilesAsync();
F1();
}
async Task writeTo(StorageFile file, byte[] write)
{
using (Stream x = await file.OpenStreamForWriteAsync())
{
x.Seek(0, SeekOrigin.End);
await x.WriteAsync(write, 0, write.Length);
}
}
async public Task<StorageFile> createEmptyFileAsync(StorageFile file)
{
StorageFolder knownFolders = KnownFolders.PicturesLibrary;
StorageFile createdFile = await knownFolders.CreateFileAsync(file.Name, CreationCollisionOption.GenerateUniqueName);
return createdFile;
}
}
The function evaluation was disabled because of an out of memory exception.
System.OutOfMemoryException at System.StubHelpers.MngdHiddenLengthArrayMarshaler.ConvertSpaceToNative(IntPtr pMarshalState, Object& pManagedHome, IntPtr pNativeHome) at Windows.Storage.Streams.DataReader.ReadBytes(Byte[] value) at TaskProblem.MainPage.<b__10_0>d.MoveNext() in C:\Users\Admin\source\repos\TaskProblem\TaskProblem\MainPage.xaml.cs:line 65