diff --git a/CHANGELOG.md b/CHANGELOG.md index bc150fa..4d34147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 31/08/2021 - v2.20.5 + +- (Add) Setting - Max degree of parallelism: Sets the maximum number of concurrent tasks/threads/operations enabled to run by parallel method calls. + If your computer lags and freeze during operations you can reduce this number to reduce the workload and keep some cores available to other tasks as well. + <= 0: Will utilize however many threads the underlying scheduler provides, mostly this is the processor count. + 1: Single thread. (#279) + ## 29/08/2021 - v2.20.4 - (Fix) On some tools, calibration tests and even files when recalculating the Z layer position for the whole set, it will use the bottom setting for all layers diff --git a/UVtools.Core/CoreSettings.cs b/UVtools.Core/CoreSettings.cs new file mode 100644 index 0000000..47f019c --- /dev/null +++ b/UVtools.Core/CoreSettings.cs @@ -0,0 +1,42 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; +using System.Threading.Tasks; + +namespace UVtools.Core +{ + public static class CoreSettings + { + #region Members + private static int _maxDegreeOfParallelism = -1; + + #endregion + + #region Properties + + /// + /// Gets or sets the maximum number of concurrent tasks enabled by this ParallelOptions instance. + /// Less or equal to 0 will set to auto number + /// 1 = Single thread + /// n = Multi threads + /// + public static int MaxDegreeOfParallelism + { + get => _maxDegreeOfParallelism; + set => _maxDegreeOfParallelism = value > 0 ? Math.Min(value, Environment.ProcessorCount) : -1; + } + + /// + /// Gets the ParallelOptions with set + /// + public static ParallelOptions ParallelOptions => new() {MaxDegreeOfParallelism = _maxDegreeOfParallelism}; + + #endregion + } +} diff --git a/UVtools.Core/FileFormats/CTBEncryptedFile.cs b/UVtools.Core/FileFormats/CTBEncryptedFile.cs index 667eea4..e37bf8c 100644 --- a/UVtools.Core/FileFormats/CTBEncryptedFile.cs +++ b/UVtools.Core/FileFormats/CTBEncryptedFile.cs @@ -1184,7 +1184,7 @@ namespace UVtools.Core.FileFormats } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -1333,7 +1333,7 @@ namespace UVtools.Core.FileFormats outputFile.Seek(outputFile.Position + layerTableSize, SeekOrigin.Begin); progress.Reset(OperationProgress.StatusEncodeLayers, LayerCount); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layerDef = new LayerDef(this, this[layerIndex]); diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs index 2fed48b..3636aac 100644 --- a/UVtools.Core/FileFormats/CWSFile.cs +++ b/UVtools.Core/FileFormats/CWSFile.cs @@ -660,7 +660,7 @@ namespace UVtools.Core.FileFormats if (Printer == PrinterType.BeneMono) { - Parallel.For(0, LayerCount, + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, //new ParallelOptions { MaxDegreeOfParallelism = Printer == PrinterType.BeneMono ? 1 : 1 }, layerIndex => { @@ -862,7 +862,7 @@ namespace UVtools.Core.FileFormats if (Printer == PrinterType.BeneMono) { - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; diff --git a/UVtools.Core/FileFormats/CXDLPFile.cs b/UVtools.Core/FileFormats/CXDLPFile.cs index 91463c3..4a2fa6a 100644 --- a/UVtools.Core/FileFormats/CXDLPFile.cs +++ b/UVtools.Core/FileFormats/CXDLPFile.cs @@ -600,7 +600,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -647,7 +647,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -710,7 +710,7 @@ namespace UVtools.Core.FileFormats } - /*Parallel.For(0, LayerCount, + /*Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, //new ParallelOptions{MaxDegreeOfParallelism = 1}, layerIndex => { @@ -822,7 +822,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -862,7 +862,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) @@ -907,7 +907,7 @@ namespace UVtools.Core.FileFormats } progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = EmguExtensions.InitMat(Resolution); diff --git a/UVtools.Core/FileFormats/CXDLPv1File.cs b/UVtools.Core/FileFormats/CXDLPv1File.cs index 5ad49a1..ee83c9b 100644 --- a/UVtools.Core/FileFormats/CXDLPv1File.cs +++ b/UVtools.Core/FileFormats/CXDLPv1File.cs @@ -518,7 +518,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -558,7 +558,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -643,7 +643,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -678,7 +678,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs index ed1d571..6854d82 100644 --- a/UVtools.Core/FileFormats/ChituboxFile.cs +++ b/UVtools.Core/FileFormats/ChituboxFile.cs @@ -1874,7 +1874,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -2105,7 +2105,7 @@ namespace UVtools.Core.FileFormats } } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayerDefinitions[0, layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/FDGFile.cs b/UVtools.Core/FileFormats/FDGFile.cs index edeae11..1a8e456 100644 --- a/UVtools.Core/FileFormats/FDGFile.cs +++ b/UVtools.Core/FileFormats/FDGFile.cs @@ -961,7 +961,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1092,7 +1092,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 04a8a3d..6163492 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -2703,7 +2703,7 @@ namespace UVtools.Core.FileFormats if (LayerCount > 0) { - Parallel.ForEach(this, (layer) => + Parallel.ForEach(this, CoreSettings.ParallelOptions, layer => { if (progress.Token.IsCancellationRequested) return; var byteArr = layer.CompressedBytes; diff --git a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs index 6c0ebea..c153037 100644 --- a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs +++ b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs @@ -505,7 +505,7 @@ namespace UVtools.Core.FileFormats SVGDocument.Groups = new List { new("background") }; var groups = new FlashForgeSVGXSvgGroup[LayerCount]; - Parallel.For(0, LayerCount, /*new ParallelOptions{MaxDegreeOfParallelism = 1},*/ layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -656,7 +656,7 @@ namespace UVtools.Core.FileFormats LayerManager.Init(SVGDocument.PrintParameters.LayerCount); progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount); - Parallel.For(0, LayerCount, /*new ParallelOptions{MaxDegreeOfParallelism = 1},*/ layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/FileFormats/GR1File.cs b/UVtools.Core/FileFormats/GR1File.cs index 77f2cce..7ef5603 100644 --- a/UVtools.Core/FileFormats/GR1File.cs +++ b/UVtools.Core/FileFormats/GR1File.cs @@ -365,7 +365,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -399,7 +399,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -483,7 +483,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -515,7 +515,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = EmguExtensions.InitMat(Resolution); diff --git a/UVtools.Core/FileFormats/LGSFile.cs b/UVtools.Core/FileFormats/LGSFile.cs index e00e6cd..9551474 100644 --- a/UVtools.Core/FileFormats/LGSFile.cs +++ b/UVtools.Core/FileFormats/LGSFile.cs @@ -529,7 +529,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -607,7 +607,7 @@ namespace UVtools.Core.FileFormats layerData[layerIndex].Parent = this; } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = layerData[layerIndex].Decode()) diff --git a/UVtools.Core/FileFormats/MDLPFile.cs b/UVtools.Core/FileFormats/MDLPFile.cs index f62c05a..fa17498 100644 --- a/UVtools.Core/FileFormats/MDLPFile.cs +++ b/UVtools.Core/FileFormats/MDLPFile.cs @@ -324,7 +324,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -358,7 +358,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -440,7 +440,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -472,7 +472,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) diff --git a/UVtools.Core/FileFormats/OSLAFile.cs b/UVtools.Core/FileFormats/OSLAFile.cs index 20e4834..2c4bad4 100644 --- a/UVtools.Core/FileFormats/OSLAFile.cs +++ b/UVtools.Core/FileFormats/OSLAFile.cs @@ -527,7 +527,7 @@ namespace UVtools.Core.FileFormats { var layerBytes = new byte[LayerCount][]; - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -687,7 +687,7 @@ namespace UVtools.Core.FileFormats layerBytes[layerIndex] = inputFile.ReadBytes(inputFile.ReadUIntLittleEndian()); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = DecodeImage(HeaderSettings.LayerDataType, layerBytes[layerIndex], Resolution)) diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs index 94f34fb..be70c04 100644 --- a/UVtools.Core/FileFormats/PHZFile.cs +++ b/UVtools.Core/FileFormats/PHZFile.cs @@ -987,7 +987,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1115,7 +1115,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/PhotonSFile.cs b/UVtools.Core/FileFormats/PhotonSFile.cs index f4492f8..292dcca 100644 --- a/UVtools.Core/FileFormats/PhotonSFile.cs +++ b/UVtools.Core/FileFormats/PhotonSFile.cs @@ -444,7 +444,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -518,7 +518,7 @@ namespace UVtools.Core.FileFormats } } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = layersDefinitions[layerIndex].Decode()) diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs index 7724596..a692b4c 100644 --- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs +++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs @@ -1325,7 +1325,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1446,7 +1446,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinition[layerIndex].Decode()) diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index 34a2603..678c298 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -630,7 +630,7 @@ namespace UVtools.Core if (_boundingRectangle.IsEmpty) // Safe checking { progress.Reset(OperationProgress.StatusOptimizingBounds, LayerCount-1); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -775,7 +775,7 @@ namespace UVtools.Core Mat GetCachedMat(uint layerIndex) { if (cachedLayers[layerIndex] is not null) return cachedLayers[layerIndex]; - Parallel.For(layerIndex, Math.Min(layerIndex + cacheCount, LayerCount), i => + Parallel.For(layerIndex, Math.Min(layerIndex + cacheCount, LayerCount), CoreSettings.ParallelOptions, i => { if (this[i].IsEmpty) return; // empty layers cachedLayers[i] = this[i].LayerMat; @@ -825,7 +825,7 @@ namespace UVtools.Core GetCachedMat(rootLayerIndex); progress.Token.ThrowIfCancellationRequested(); uint layerAdvance = (uint) Math.Min(i + cacheCount, actionLayers.Count); - Parallel.For(i, layerAdvance, l => + Parallel.For(i, layerAdvance, CoreSettings.ParallelOptions, l => { var layerIndex = actionLayers[(int) l]; var layer = this[layerIndex]; @@ -1007,9 +1007,7 @@ namespace UVtools.Core progress.Reset(OperationProgress.StatusIslands, LayerCount); // Detect contours - Parallel.ForEach(this, - //new ParallelOptions{MaxDegreeOfParallelism = 1}, - layer => + Parallel.ForEach(this, CoreSettings.ParallelOptions, layer => { if (progress.Token.IsCancellationRequested) return; if (layer.IsEmpty) @@ -1422,8 +1420,8 @@ namespace UVtools.Core //foreach (var area in areas) //Parallel.ForEach(from t in areas where t.Type == LayerHollowArea.AreaType.Unknown select t, - // new ParallelOptions{MaxDegreeOfParallelism = 1}, area => - foreach(var area in areas) + // CoreSettings.ParallelOptions, area => + foreach (var area in areas) { //if (progress.Token.IsCancellationRequested) return; if (area.Type != LayerHollowArea.AreaType.Unknown) continue; // processed, ignore @@ -1437,7 +1435,7 @@ namespace UVtools.Core //List linkedAreas = new(); for (sbyte dir = 1; dir >= -1 && area.Type != LayerHollowArea.AreaType.Drain; dir -= 2) - //Parallel.ForEach(new sbyte[] {1, -1}, new ParallelOptions {MaxDegreeOfParallelism = 2}, dir => + //Parallel.ForEach(new sbyte[] {1, -1}, CoreSettings.ParallelOptions, dir => { Queue queue = new(); queue.Enqueue(area); @@ -1783,7 +1781,7 @@ namespace UVtools.Core } progress.Reset("Saving", (uint) modifiedLayers.Count); - Parallel.ForEach(modifiedLayers, (modifiedLayer, state) => + Parallel.ForEach(modifiedLayers, CoreSettings.ParallelOptions, modifiedLayer => { this[modifiedLayer.Key].LayerMat = modifiedLayer.Value; modifiedLayer.Value.Dispose(); @@ -1835,7 +1833,7 @@ namespace UVtools.Core Array.Resize(ref _layers, (int) newLayerCount); if (differenceLayerCount > 0 && initBlack) { - Parallel.For(oldLayerCount, newLayerCount, layerIndex => + Parallel.For(oldLayerCount, newLayerCount, CoreSettings.ParallelOptions, layerIndex => { this[layerIndex] = new Layer((uint)layerIndex, EmguExtensions.InitMat(SlicerFile.Resolution), this); }); @@ -1866,7 +1864,7 @@ namespace UVtools.Core // Allocate new layers if (initBlack) { - Parallel.For(insertAtLayerIndex, insertAtLayerIndex + layerCount, layerIndex => + Parallel.For(insertAtLayerIndex, insertAtLayerIndex + layerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint) layerIndex, EmguExtensions.InitMat(SlicerFile.Resolution), this); }); @@ -1917,7 +1915,7 @@ namespace UVtools.Core public Layer[] AllocateFromMat(Mat[] mats) { var layers = new Layer[mats.Length]; - Parallel.For(0L, mats.Length, i => + Parallel.For(0L, mats.Length, CoreSettings.ParallelOptions, i => { layers[i] = new Layer((uint)i, mats[i], this); }); diff --git a/UVtools.Core/Operations/OperationBlur.cs b/UVtools.Core/Operations/OperationBlur.cs index 9642812..7ec4de9 100644 --- a/UVtools.Core/Operations/OperationBlur.cs +++ b/UVtools.Core/Operations/OperationBlur.cs @@ -132,7 +132,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) diff --git a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs index 74da586..b400c6a 100644 --- a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs +++ b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs @@ -661,7 +661,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } // Preview diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs index 11ed778..b69a64d 100644 --- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs +++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs @@ -1883,7 +1883,7 @@ namespace UVtools.Core.Operations var tableGrouped = table.GroupBy(pair => new {pair.Key.LayerHeight, pair.Key.BottomExposure, pair.Key.Exposure}).Distinct(); SlicerFile.BottomLayerCount = _bottomLayers; progress.ItemCount = (uint) (SlicerFile.LayerCount * table.Count); - Parallel.For(0, SlicerFile.LayerCount, layerIndex => + Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationCalibrateGrayscale.cs b/UVtools.Core/Operations/OperationCalibrateGrayscale.cs index 47308d3..308e7fe 100644 --- a/UVtools.Core/Operations/OperationCalibrateGrayscale.cs +++ b/UVtools.Core/Operations/OperationCalibrateGrayscale.cs @@ -449,7 +449,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; diff --git a/UVtools.Core/Operations/OperationCalibrateStressTower.cs b/UVtools.Core/Operations/OperationCalibrateStressTower.cs index 70df44d..9f8c8b6 100644 --- a/UVtools.Core/Operations/OperationCalibrateStressTower.cs +++ b/UVtools.Core/Operations/OperationCalibrateStressTower.cs @@ -333,19 +333,19 @@ namespace UVtools.Core.Operations var anchor = new Point(-1, -1); var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);*/ - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { layers[layerIndex] = EmguExtensions.InitMat(SlicerFile.Resolution); }); - Parallel.For(0, baseLayers, layerIndex => + Parallel.For(0, baseLayers, CoreSettings.ParallelOptions, layerIndex => { int chamferOffset = (int) Math.Max(0, _chamferLayers - layerIndex); CvInvoke.Circle(layers[layerIndex], center, (int) baseRadius - chamferOffset, EmguExtensions.WhiteColor, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected); }); - Parallel.For(0, baseLayers+bodyLayers, layerIndex => + Parallel.For(0, baseLayers+bodyLayers, CoreSettings.ParallelOptions, layerIndex => { decimal angle = (layerIndex * _spiralAngleStepPerLayer) % 360m; for (byte spiral = 0; spiral < _spirals; spiral++) @@ -375,7 +375,7 @@ namespace UVtools.Core.Operations currrentlayer += bodyLayers; - Parallel.For(0, ceilLayers, i => + Parallel.For(0, ceilLayers, CoreSettings.ParallelOptions, i => { uint layerIndex = (uint)(currrentlayer + i); CvInvoke.Circle(layers[layerIndex], center, (int)baseRadius, EmguExtensions.WhiteColor, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected); @@ -387,7 +387,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; @@ -418,7 +418,7 @@ namespace UVtools.Core.Operations var layers = GetLayers(); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint)layerIndex, layers[layerIndex], SlicerFile.LayerManager) {IsModified = true}; layers[layerIndex].Dispose(); diff --git a/UVtools.Core/Operations/OperationCalibrateTolerance.cs b/UVtools.Core/Operations/OperationCalibrateTolerance.cs index a6a8f50..a23bcb3 100644 --- a/UVtools.Core/Operations/OperationCalibrateTolerance.cs +++ b/UVtools.Core/Operations/OperationCalibrateTolerance.cs @@ -638,7 +638,7 @@ namespace UVtools.Core.Operations if (!addPart(step)) break; } - Parallel.For(0, layers.Length, layerIndex => + Parallel.For(0, layers.Length, CoreSettings.ParallelOptions, layerIndex => //for (var i = 0; i < layers.Length; i++) { layers[layerIndex] = layer.Clone(); @@ -646,7 +646,7 @@ namespace UVtools.Core.Operations if (_erodeBottomIterations > 0) { - Parallel.For(0, _bottomLayers, layerIndex => + Parallel.For(0, _bottomLayers, CoreSettings.ParallelOptions, layerIndex => { CvInvoke.Erode(layers[layerIndex], layers[layerIndex], kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default); }); @@ -654,7 +654,7 @@ namespace UVtools.Core.Operations if (_chamferLayers > 0) { - Parallel.For(0, _chamferLayers, layerIndexOffset => + Parallel.For(0, _chamferLayers, CoreSettings.ParallelOptions, layerIndexOffset => { var iteration = _chamferLayers - layerIndexOffset; CvInvoke.Erode(layers[layerIndexOffset], layers[layerIndexOffset], kernel, anchor, iteration, BorderType.Reflect101, default); @@ -676,7 +676,7 @@ namespace UVtools.Core.Operations }*/ } - Parallel.For(Math.Max(0u, LayerCount - 15), LayerCount, layerIndex => + Parallel.For(Math.Max(0u, LayerCount - 15), LayerCount, CoreSettings.ParallelOptions, layerIndex => { foreach (var keyValuePair in pointTextList) { @@ -688,7 +688,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; @@ -730,7 +730,7 @@ namespace UVtools.Core.Operations var layers = GetLayers(); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint)layerIndex, layers[layerIndex], SlicerFile.LayerManager) {IsModified = true}; layers[layerIndex].Dispose(); diff --git a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs index 92c0564..62996e4 100644 --- a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs +++ b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs @@ -721,7 +721,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; diff --git a/UVtools.Core/Operations/OperationChangeResolution.cs b/UVtools.Core/Operations/OperationChangeResolution.cs index a43fdbe..505978b 100644 --- a/UVtools.Core/Operations/OperationChangeResolution.cs +++ b/UVtools.Core/Operations/OperationChangeResolution.cs @@ -162,7 +162,7 @@ namespace UVtools.Core.Operations progress.ItemCount = SlicerFile.LayerCount; var boundingRectangle = SlicerFile.BoundingRectangle; var newSize = new Size((int) NewResolutionX, (int) NewResolutionY); - Parallel.For(0, SlicerFile.LayerCount, layerIndex => + Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs index e503ab6..321a815 100644 --- a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs +++ b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs @@ -588,7 +588,7 @@ namespace UVtools.Core.Operations matThresholdCache[layerIndex].Dispose(); matThresholdCache[layerIndex] = null; } - Parallel.For(fromLayerIndex, Math.Min(fromLayerIndex + CacheObjectCount, SlicerFile.LayerCount), layerIndex => + Parallel.For(fromLayerIndex, Math.Min(fromLayerIndex + CacheObjectCount, SlicerFile.LayerCount), CoreSettings.ParallelOptions, layerIndex => { if (matCache[layerIndex] is not null) return; // Already cached matCache[layerIndex] = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationFlip.cs b/UVtools.Core/Operations/OperationFlip.cs index 3510d3e..e9c2a43 100644 --- a/UVtools.Core/Operations/OperationFlip.cs +++ b/UVtools.Core/Operations/OperationFlip.cs @@ -100,7 +100,7 @@ namespace UVtools.Core.Operations #region Methods protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationInfill.cs b/UVtools.Core/Operations/OperationInfill.cs index 0793da7..b2ab150 100644 --- a/UVtools.Core/Operations/OperationInfill.cs +++ b/UVtools.Core/Operations/OperationInfill.cs @@ -135,7 +135,7 @@ namespace UVtools.Core.Operations mask = GetHoneycombMask(GetRoiSizeOrDefault()); } - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerArithmetic.cs b/UVtools.Core/Operations/OperationLayerArithmetic.cs index 721f8c9..e3a8411 100644 --- a/UVtools.Core/Operations/OperationLayerArithmetic.cs +++ b/UVtools.Core/Operations/OperationLayerArithmetic.cs @@ -288,7 +288,7 @@ namespace UVtools.Core.Operations } progress.Reset("Applied layers", (uint) SetLayers.Count); - Parallel.ForEach(SetLayers, layerIndex => + Parallel.ForEach(SetLayers, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; progress.LockAndIncrement(); diff --git a/UVtools.Core/Operations/OperationLayerExportGif.cs b/UVtools.Core/Operations/OperationLayerExportGif.cs index ae93843..c3d5f78 100644 --- a/UVtools.Core/Operations/OperationLayerExportGif.cs +++ b/UVtools.Core/Operations/OperationLayerExportGif.cs @@ -219,7 +219,7 @@ namespace UVtools.Core.Operations ROI = SlicerFile.BoundingRectangle; } - Parallel.For(0, TotalLayers, i => + Parallel.For(0, TotalLayers, CoreSettings.ParallelOptions, i => { if (progress.Token.IsCancellationRequested) return; uint layerIndex = (uint) (LayerIndexStart + i * (_skip + 1)); diff --git a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs index 3817514..9263f28 100644 --- a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs +++ b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs @@ -101,7 +101,7 @@ namespace UVtools.Core.Operations using var mask = GetMask(sumMat32); - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerExportImage.cs b/UVtools.Core/Operations/OperationLayerExportImage.cs index 5925b67..5748662 100644 --- a/UVtools.Core/Operations/OperationLayerExportImage.cs +++ b/UVtools.Core/Operations/OperationLayerExportImage.cs @@ -172,7 +172,7 @@ namespace UVtools.Core.Operations var slicedFileNameNoExt = SlicerFile.FilenameNoExt; - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerExportSkeleton.cs b/UVtools.Core/Operations/OperationLayerExportSkeleton.cs index 0fd56d0..9197c5f 100644 --- a/UVtools.Core/Operations/OperationLayerExportSkeleton.cs +++ b/UVtools.Core/Operations/OperationLayerExportSkeleton.cs @@ -86,7 +86,7 @@ namespace UVtools.Core.Operations using var mask = GetMask(skeletonSum); - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs index c2997ee..6a05590 100644 --- a/UVtools.Core/Operations/OperationLayerImport.cs +++ b/UVtools.Core/Operations/OperationLayerImport.cs @@ -73,7 +73,7 @@ namespace UVtools.Core.Operations public override string ValidateInternally() { /*var result = new ConcurrentBag(); - Parallel.ForEach(Files, file => + Parallel.ForEach(Files, CoreSettings.ParallelOptions, file => { using (Mat mat = CvInvoke.Imread(file.TagString, ImreadModes.AnyColor)) { @@ -238,7 +238,7 @@ namespace UVtools.Core.Operations SL1File format = new(); format.LayerManager.Init((uint)keyImage.Count); - Parallel.ForEach(keyImage, pair => + Parallel.ForEach(keyImage, CoreSettings.ParallelOptions, pair => { if (progress.Token.IsCancellationRequested) return; using var mat = CvInvoke.Imread(pair.Value, ImreadModes.Grayscale); @@ -360,9 +360,7 @@ namespace UVtools.Core.Operations } progress.Reset(ProgressAction, fileFormat.LayerCount); - Parallel.For(0, fileFormat.LayerCount, - //new ParallelOptions{MaxDegreeOfParallelism = 1}, - i => + Parallel.For(0, fileFormat.LayerCount, CoreSettings.ParallelOptions, i => { if (progress.Token.IsCancellationRequested) return; uint layerIndex = (uint)(_startLayerIndex + i); diff --git a/UVtools.Core/Operations/OperationLayerReHeight.cs b/UVtools.Core/Operations/OperationLayerReHeight.cs index a7f8d30..44f153d 100644 --- a/UVtools.Core/Operations/OperationLayerReHeight.cs +++ b/UVtools.Core/Operations/OperationLayerReHeight.cs @@ -220,7 +220,7 @@ namespace UVtools.Core.Operations layerIndexes[i] = i * _selectedItem.Modifier; } - Parallel.ForEach(layerIndexes, layerIndex => + Parallel.ForEach(layerIndexes, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var oldLayer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationLightBleedCompensation.cs b/UVtools.Core/Operations/OperationLightBleedCompensation.cs index c3175af..dd86654 100644 --- a/UVtools.Core/Operations/OperationLightBleedCompensation.cs +++ b/UVtools.Core/Operations/OperationLightBleedCompensation.cs @@ -203,7 +203,7 @@ namespace UVtools.Core.Operations { var dimMats = GetDimMats(); if (dimMats.Length == 0) return false; - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.Core/Operations/OperationMask.cs b/UVtools.Core/Operations/OperationMask.cs index c310ae5..8b35a39 100644 --- a/UVtools.Core/Operations/OperationMask.cs +++ b/UVtools.Core/Operations/OperationMask.cs @@ -75,7 +75,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationMorph.cs b/UVtools.Core/Operations/OperationMorph.cs index 8c5f561..bdb29ad 100644 --- a/UVtools.Core/Operations/OperationMorph.cs +++ b/UVtools.Core/Operations/OperationMorph.cs @@ -155,9 +155,7 @@ namespace UVtools.Core.Operations out var maxIteration ); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, - //new ParallelOptions {MaxDegreeOfParallelism = 1}, - layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; int iterations = LayerManager.MutateGetIterationVar(isFade, (int)IterationsStart, (int)IterationsEnd, iterationSteps, maxIteration, LayerIndexStart, (uint)layerIndex); diff --git a/UVtools.Core/Operations/OperationMove.cs b/UVtools.Core/Operations/OperationMove.cs index deb3829..8b82d29 100644 --- a/UVtools.Core/Operations/OperationMove.cs +++ b/UVtools.Core/Operations/OperationMove.cs @@ -284,7 +284,7 @@ namespace UVtools.Core.Operations if (ROI.IsEmpty) ROI = SlicerFile.LayerManager.GetBoundingRectangle(progress); CalculateDstRoi(); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationPattern.cs b/UVtools.Core/Operations/OperationPattern.cs index 163980d..9e668b2 100644 --- a/UVtools.Core/Operations/OperationPattern.cs +++ b/UVtools.Core/Operations/OperationPattern.cs @@ -298,7 +298,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationPixelArithmetic.cs b/UVtools.Core/Operations/OperationPixelArithmetic.cs index b6a1b9c..12fab9f 100644 --- a/UVtools.Core/Operations/OperationPixelArithmetic.cs +++ b/UVtools.Core/Operations/OperationPixelArithmetic.cs @@ -494,7 +494,7 @@ namespace UVtools.Core.Operations } - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) @@ -839,7 +839,7 @@ namespace UVtools.Core.Operations { var result = new string[mat.Height]; var span = mat.GetBytePointer(); - Parallel.For(0, mat.Height, y => + Parallel.For(0, mat.Height, CoreSettings.ParallelOptions, y => { result[y] = string.Empty; var pixelPos = mat.GetPixelPos(0, y); diff --git a/UVtools.Core/Operations/OperationPixelDimming.cs b/UVtools.Core/Operations/OperationPixelDimming.cs index 97df8bd..070e6ce 100644 --- a/UVtools.Core/Operations/OperationPixelDimming.cs +++ b/UVtools.Core/Operations/OperationPixelDimming.cs @@ -296,7 +296,7 @@ namespace UVtools.Core.Operations { var result = new string[mat.Height]; var span = mat.GetBytePointer(); - Parallel.For(0, mat.Height, y => + Parallel.For(0, mat.Height, CoreSettings.ParallelOptions, y => { result[y] = string.Empty; for (int x = 0; x < mat.Width; x++) @@ -649,7 +649,7 @@ namespace UVtools.Core.Operations CvInvoke.BitwiseNot(patternMask, patternMask); CvInvoke.BitwiseNot(alternatePatternMask, alternatePatternMask); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs index 52401ee..d59d217 100644 --- a/UVtools.Core/Operations/OperationRaftRelief.cs +++ b/UVtools.Core/Operations/OperationRaftRelief.cs @@ -239,7 +239,7 @@ namespace UVtools.Core.Operations } progress.Reset(ProgressAction, firstSupportLayerIndex - _ignoreFirstLayers); - Parallel.For(_ignoreFirstLayers, firstSupportLayerIndex, layerIndex => + Parallel.For(_ignoreFirstLayers, firstSupportLayerIndex, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationRedrawModel.cs b/UVtools.Core/Operations/OperationRedrawModel.cs index abcc4be..cd23236 100644 --- a/UVtools.Core/Operations/OperationRedrawModel.cs +++ b/UVtools.Core/Operations/OperationRedrawModel.cs @@ -167,7 +167,7 @@ namespace UVtools.Core.Operations int startLayerIndex = (int)(SlicerFile.LayerCount - otherFile.LayerCount); if (startLayerIndex < 0) return false; - Parallel.For(0, otherFile.LayerCount, layerIndex => + Parallel.For(0, otherFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var fullMatLayerIndex = startLayerIndex + layerIndex; diff --git a/UVtools.Core/Operations/OperationRepairLayers.cs b/UVtools.Core/Operations/OperationRepairLayers.cs index cdafcc3..c554e26 100644 --- a/UVtools.Core/Operations/OperationRepairLayers.cs +++ b/UVtools.Core/Operations/OperationRepairLayers.cs @@ -179,7 +179,7 @@ namespace UVtools.Core.Operations if (!issuesGroup.Any()) break; // Nothing to process islandsToRecompute.Clear(); - Parallel.ForEach(issuesGroup, group => + Parallel.ForEach(issuesGroup, CoreSettings.ParallelOptions, group => { if (progress.Token.IsCancellationRequested) return; Layer layer = SlicerFile[group.Key]; @@ -234,7 +234,7 @@ namespace UVtools.Core.Operations progress.Reset("Attempt to attach islands below", (uint) islandsToProcess.Count); - Parallel.ForEach(issuesGroup, group => + Parallel.ForEach(issuesGroup, CoreSettings.ParallelOptions, group => { using var mat = SlicerFile[group.Key].LayerMat; var matSpan = mat.GetDataByteSpan(); @@ -319,7 +319,7 @@ namespace UVtools.Core.Operations progress.Reset(ProgressAction, LayerRangeCount); if (_repairIslands || _repairResinTraps) { - Parallel.For(LayerIndexStart, LayerIndexEnd, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationResize.cs b/UVtools.Core/Operations/OperationResize.cs index b3d6c50..394e4ac 100644 --- a/UVtools.Core/Operations/OperationResize.cs +++ b/UVtools.Core/Operations/OperationResize.cs @@ -156,7 +156,7 @@ namespace UVtools.Core.Operations decimal xSteps = Math.Abs(100 - _x) / (LayerIndexEnd - LayerIndexStart + 1); decimal ySteps = Math.Abs(100 - _y) / (LayerIndexEnd - LayerIndexStart + 1); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var newX = _x; diff --git a/UVtools.Core/Operations/OperationRotate.cs b/UVtools.Core/Operations/OperationRotate.cs index fe9e215..717762c 100644 --- a/UVtools.Core/Operations/OperationRotate.cs +++ b/UVtools.Core/Operations/OperationRotate.cs @@ -84,7 +84,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationSolidify.cs b/UVtools.Core/Operations/OperationSolidify.cs index b689799..f108953 100644 --- a/UVtools.Core/Operations/OperationSolidify.cs +++ b/UVtools.Core/Operations/OperationSolidify.cs @@ -86,7 +86,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationThreshold.cs b/UVtools.Core/Operations/OperationThreshold.cs index 4754f00..47faf36 100644 --- a/UVtools.Core/Operations/OperationThreshold.cs +++ b/UVtools.Core/Operations/OperationThreshold.cs @@ -81,7 +81,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index a8558b4..5de153d 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ https://github.com/sn4k3/UVtools https://github.com/sn4k3/UVtools MSLA/DLP, file analysis, calibration, repair, conversion and manipulation - 2.20.4 + 2.20.5 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.ScriptSample/ScriptInsetSample.cs b/UVtools.ScriptSample/ScriptInsetSample.cs index 015fe04..9b6de73 100644 --- a/UVtools.ScriptSample/ScriptInsetSample.cs +++ b/UVtools.ScriptSample/ScriptInsetSample.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using UVtools.Core.Scripting; using Emgu.CV; using Emgu.CV.CvEnum; +using UVtools.Core; namespace UVtools.ScriptSample { @@ -90,7 +91,7 @@ namespace UVtools.ScriptSample Progress.Reset("Inset layers", Operation.LayerRangeCount); // Sets the progress name and number of items to process // Loop user selected layers in parallel, this will put each core of CPU working here on parallel - Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, layerIndex => + Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (Progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs b/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs index b7fc518..d272108 100644 --- a/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs +++ b/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using UVtools.Core.Scripting; using Emgu.CV; using Emgu.CV.Structure; +using UVtools.Core; using UVtools.Core.Extensions; namespace UVtools.ScriptSample @@ -86,7 +87,7 @@ namespace UVtools.ScriptSample var brightnesses = Levels; // Loop user selected layers in parallel, this will put each core of CPU working here on parallel - Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, layerIndex => + Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (Progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.WPF/MainWindow.Issues.cs b/UVtools.WPF/MainWindow.Issues.cs index 0e9def1..1308b0e 100644 --- a/UVtools.WPF/MainWindow.Issues.cs +++ b/UVtools.WPF/MainWindow.Issues.cs @@ -116,7 +116,7 @@ namespace UVtools.WPF bool result = false; try { - Parallel.ForEach(processIssues, layerIssues => + Parallel.ForEach(processIssues, CoreSettings.ParallelOptions, layerIssues => { if (Progress.Token.IsCancellationRequested) return; using (var image = SlicerFile[layerIssues.Key].LayerMat) diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs index 5a047bd..4e94c57 100644 --- a/UVtools.WPF/MainWindow.LayerPreview.cs +++ b/UVtools.WPF/MainWindow.LayerPreview.cs @@ -796,7 +796,7 @@ namespace UVtools.WPF bool showSimilarityInstead = Settings.LayerPreview.LayerDifferenceHighlightSimilarityInstead; - Parallel.For(rect.Y, rect.Bottom, y => + Parallel.For(rect.Y, rect.Bottom, CoreSettings.ParallelOptions, y => { for (int x = rect.X; x < rect.Right; x++) { diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 1b1922b..3f1d96f 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ LICENSE https://github.com/sn4k3/UVtools Git - 2.20.4 + 2.20.5 diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs index 2ac29c6..b76150e 100644 --- a/UVtools.WPF/UserSettings.cs +++ b/UVtools.WPF/UserSettings.cs @@ -9,6 +9,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Threading.Tasks; using System.Xml.Serialization; using Avalonia.Media; using JetBrains.Annotations; @@ -22,7 +23,7 @@ namespace UVtools.WPF public sealed class UserSettings : BindableBase { #region Constants - public const ushort SETTINGS_VERSION = 4; + public const ushort SETTINGS_VERSION = 5; #endregion #region Sub classes @@ -34,6 +35,8 @@ namespace UVtools.WPF private bool _startMaximized = true; private bool _checkForUpdatesOnStartup = true; private bool _loadDemoFileOnStartup = true; + private int _maxDegreeOfParallelism = -1; + private bool _windowsCanResize; private bool _windowsTakeIntoAccountScreenScaling = true; private ushort _windowsHorizontalMargin = 100; @@ -48,7 +51,6 @@ namespace UVtools.WPF private bool _promptOverwriteFileSave = true; private string _fileSaveNamePrefix; private string _fileSaveNameSuffix = "_copy"; - private int _maxDegreeOfParallelism; public bool StartMaximized @@ -69,6 +71,15 @@ namespace UVtools.WPF set => RaiseAndSetIfChanged(ref _loadDemoFileOnStartup, value); } + /// + /// Gets or sets the maximum number of concurrent tasks enabled by a ParallelOptions instance. + /// + public int MaxDegreeOfParallelism + { + get => _maxDegreeOfParallelism; + set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, Math.Min(value, Environment.ProcessorCount)); + } + public bool WindowsCanResize { get => _windowsCanResize; @@ -154,19 +165,7 @@ namespace UVtools.WPF set => RaiseAndSetIfChanged(ref _fileSaveNameSuffix, value); } - /// - /// Gets or sets the maximum number of concurrent tasks enabled by a ParallelOptions instance. - /// - public int MaxDegreeOfParallelism - { - get => _maxDegreeOfParallelism; - set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, value); - } - - public GeneralUserSettings() - { - MaxDegreeOfParallelism = Environment.ProcessorCount; - } + public GeneralUserSettings() { } public GeneralUserSettings Clone() { @@ -1417,16 +1416,26 @@ namespace UVtools.WPF using var myXmlReader = new StreamReader(FilePath); _instance = (UserSettings)serializer.Deserialize(myXmlReader); if (_instance.General.MaxDegreeOfParallelism <= 0) - _instance.General.MaxDegreeOfParallelism = Environment.ProcessorCount; + { + _instance.General.MaxDegreeOfParallelism = -1; + } + else + { + _instance.General.MaxDegreeOfParallelism = Math.Min(_instance.General.MaxDegreeOfParallelism, Environment.ProcessorCount); + } + if (_instance.SettingsVersion < SETTINGS_VERSION) { // Upgrade - + if (_instance.SettingsVersion <= 4) + { + _instance.General.MaxDegreeOfParallelism = -1; + } _instance.SettingsVersion = SETTINGS_VERSION; } - + CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; } catch (Exception e) { @@ -1443,6 +1452,7 @@ namespace UVtools.WPF { Instance.SavesCount++; _instance.ModifiedDateTime = DateTime.Now; + CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; var serializer = new XmlSerializer(_instance.GetType()); try { diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml index e6e5e26..6389676 100644 --- a/UVtools.WPF/Windows/SettingsWindow.axaml +++ b/UVtools.WPF/Windows/SettingsWindow.axaml @@ -32,6 +32,93 @@ + + + + + + + + + + + + +