Upgraded Nuget packages. Added a new For function for executing a for loop in parallel. Added unit tests. Bumped package version to 1.0.2
This commit is contained in:
		| @@ -11,14 +11,14 @@ | |||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="FluentAssertions" Version="6.11.0" /> |     <PackageReference Include="FluentAssertions" Version="6.12.2" /> | ||||||
|     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> |     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> | ||||||
|     <PackageReference Include="xunit" Version="2.4.2" /> |     <PackageReference Include="xunit" Version="2.9.2" /> | ||||||
|     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> |     <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2"> | ||||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|       <PrivateAssets>all</PrivateAssets> |       <PrivateAssets>all</PrivateAssets> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="coverlet.collector" Version="3.2.0"> |     <PackageReference Include="coverlet.collector" Version="6.0.2"> | ||||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|       <PrivateAssets>all</PrivateAssets> |       <PrivateAssets>all</PrivateAssets> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|   | |||||||
| @@ -147,5 +147,41 @@ namespace MontoyaTech.Parallel.Net.Tests | |||||||
|  |  | ||||||
|             results.Should().Be(5); |             results.Should().Be(5); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         [Fact] | ||||||
|  |         public void Parallel_For_Odd_Should_Work() | ||||||
|  |         { | ||||||
|  |             var indexes = new List<long>(); | ||||||
|  |  | ||||||
|  |             ParallelTask.For(0, 3, index => | ||||||
|  |             { | ||||||
|  |                 lock (indexes) | ||||||
|  |                     indexes.Add(index); | ||||||
|  |             }, 2); | ||||||
|  |  | ||||||
|  |             indexes.Count.Should().Be(3); | ||||||
|  |  | ||||||
|  |             for (long i = 0; i < 3; i++) | ||||||
|  |                 if (!indexes.Contains(i)) | ||||||
|  |                     throw new Exception($"Test failed, missing index: {i}"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [Fact] | ||||||
|  |         public void Parallel_For_Even_Should_Work() | ||||||
|  |         { | ||||||
|  |             var indexes = new List<long>(); | ||||||
|  |  | ||||||
|  |             ParallelTask.For(0, 4, index => | ||||||
|  |             { | ||||||
|  |                 lock (indexes) | ||||||
|  |                     indexes.Add(index); | ||||||
|  |             }, 2); | ||||||
|  |  | ||||||
|  |             indexes.Count.Should().Be(4); | ||||||
|  |  | ||||||
|  |             for (long i = 0; i < 4; i++) | ||||||
|  |                 if (!indexes.Contains(i)) | ||||||
|  |                     throw new Exception($"Test failed, missing index: {i}"); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
|     <PackageIcon>Logo_Symbol_Black_Outline.png</PackageIcon> |     <PackageIcon>Logo_Symbol_Black_Outline.png</PackageIcon> | ||||||
|     <RepositoryUrl>https://code.montoyatech.com/MontoyaTech/Parallel.Net</RepositoryUrl> |     <RepositoryUrl>https://code.montoyatech.com/MontoyaTech/Parallel.Net</RepositoryUrl> | ||||||
|     <GenerateDocumentationFile>True</GenerateDocumentationFile> |     <GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||||
|     <Version>1.0.1</Version> |     <Version>1.0.2</Version> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|   | |||||||
| @@ -216,6 +216,63 @@ namespace MontoyaTech.Parallel.Net | |||||||
|                         throw tasks[i].ThrownException; |                         throw tasks[i].ThrownException; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Runs an action for loop in parallel where index greaterthanorequal start and index lessthan end. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="start">The starting index.</param> | ||||||
|  |         /// <param name="end">The ending index, index is always less than this value.</param> | ||||||
|  |         /// <param name="action">The paramter is the index from the loop.</param> | ||||||
|  |         /// <param name="maxTasks">The max number of tasks to run in parallel. If null the number of available cores is used. Default is null.</param> | ||||||
|  |         /// <param name="timeout">If set this function will return early if the tieout is reached even if the tasks are not done. Default is null.</param> | ||||||
|  |         /// <param name="throwOnTimeout">If true an exception will be thrown if a timeout is reached is one was set. Default is true.</param> | ||||||
|  |         /// <param name="bubbleExceptions">If true, rethrows any exceptions from the running tasks. Default is true.</param> | ||||||
|  |         public static void For(long start, long end, Action<long> action, int? maxTasks = null, TimeSpan? timeout = null, bool throwOnTimeout = true, bool bubbleExceptions = true) | ||||||
|  |         { | ||||||
|  |             if (start == 0 && end == start) | ||||||
|  |                 return; | ||||||
|  |             else if (start >= end) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             var tasks = new List<ParallelTask<(long chunkStart, long chunkEnd)>>(); | ||||||
|  |  | ||||||
|  |             if (!maxTasks.HasValue) | ||||||
|  |                 maxTasks = Environment.ProcessorCount; | ||||||
|  |             else if (maxTasks <= 0) | ||||||
|  |                 maxTasks = 1; | ||||||
|  |  | ||||||
|  |             long itemsPerChunk = ((end - start) / (long)maxTasks.Value) + 1; | ||||||
|  |  | ||||||
|  |             long index = start; | ||||||
|  |             for (int i = 0; i < maxTasks.Value; i++) | ||||||
|  |             { | ||||||
|  |                 var chunkStart = index; | ||||||
|  |                 var chunkEnd = index + itemsPerChunk; | ||||||
|  |                 index += itemsPerChunk; | ||||||
|  |  | ||||||
|  |                 if (chunkEnd > end) | ||||||
|  |                     chunkEnd = end; | ||||||
|  |  | ||||||
|  |                 tasks.Add(new ParallelTask<(long chunkStart, long chunkEnd)>(state => | ||||||
|  |                 { | ||||||
|  |                     for (long i = state.chunkStart; i < state.chunkEnd; i++) | ||||||
|  |                         action(i); | ||||||
|  |                 }, (chunkStart, chunkEnd))); | ||||||
|  |  | ||||||
|  |                 if (index >= end) | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (tasks.Count == 0) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             WhenAll(tasks, timeout, throwOnTimeout); | ||||||
|  |  | ||||||
|  |             if (bubbleExceptions) | ||||||
|  |                 for (int i = 0; i < tasks.Count; i++) | ||||||
|  |                     if (tasks[i].Failed && tasks[i].ThrownException != null) | ||||||
|  |                         throw tasks[i].ThrownException; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Runs a list of tasks and waits until they have been completed or failed and returns the results. |         /// Runs a list of tasks and waits until they have been completed or failed and returns the results. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user