From c0bce62115b33bc9acb96ecf76aac82034122f78 Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 13 Oct 2025 20:17:01 +0300 Subject: [PATCH 1/7] init project HW3 --- HW3/HW3.sln | 16 ++++++++++++++++ HW3/threadPool/stylecop.json | 9 +++++++++ HW3/threadPool/threadPool.csproj | 21 +++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 HW3/HW3.sln create mode 100644 HW3/threadPool/stylecop.json create mode 100644 HW3/threadPool/threadPool.csproj diff --git a/HW3/HW3.sln b/HW3/HW3.sln new file mode 100644 index 0000000..5a3dfd7 --- /dev/null +++ b/HW3/HW3.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "threadPool", "threadPool\threadPool.csproj", "{FA31B85A-23F0-4566-8D57-08FA33575C42}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA31B85A-23F0-4566-8D57-08FA33575C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA31B85A-23F0-4566-8D57-08FA33575C42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA31B85A-23F0-4566-8D57-08FA33575C42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA31B85A-23F0-4566-8D57-08FA33575C42}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/HW3/threadPool/stylecop.json b/HW3/threadPool/stylecop.json new file mode 100644 index 0000000..76c8e76 --- /dev/null +++ b/HW3/threadPool/stylecop.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "khusainovilas", + "copyrightText": "Copyright (c) {companyName}. All rights reserved." + } + } +} \ No newline at end of file diff --git a/HW3/threadPool/threadPool.csproj b/HW3/threadPool/threadPool.csproj new file mode 100644 index 0000000..806b616 --- /dev/null +++ b/HW3/threadPool/threadPool.csproj @@ -0,0 +1,21 @@ + + + + Exe + net9.0 + enable + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + From aaa0310033274f77ea405dd05bc51350ea7043b9 Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 13 Oct 2025 21:18:10 +0300 Subject: [PATCH 2/7] add IMyTask interface --- HW3/HW3.sln | 2 +- HW3/MyThreadPool/IMyTask.cs | 34 +++++++++++++++++++ HW3/MyThreadPool/MyThreadPool.cs | 13 +++++++ HW3/MyThreadPool/MyThreadPool.csproj | 22 ++++++++++++ .../stylecop.json | 3 +- HW3/threadPool/threadPool.csproj | 21 ------------ 6 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 HW3/MyThreadPool/IMyTask.cs create mode 100644 HW3/MyThreadPool/MyThreadPool.cs create mode 100644 HW3/MyThreadPool/MyThreadPool.csproj rename HW3/{threadPool => MyThreadPool}/stylecop.json (89%) delete mode 100644 HW3/threadPool/threadPool.csproj diff --git a/HW3/HW3.sln b/HW3/HW3.sln index 5a3dfd7..71535c8 100644 --- a/HW3/HW3.sln +++ b/HW3/HW3.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "threadPool", "threadPool\threadPool.csproj", "{FA31B85A-23F0-4566-8D57-08FA33575C42}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool", "MyThreadPool\MyThreadPool.csproj", "{FA31B85A-23F0-4566-8D57-08FA33575C42}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/HW3/MyThreadPool/IMyTask.cs b/HW3/MyThreadPool/IMyTask.cs new file mode 100644 index 0000000..2b67fe5 --- /dev/null +++ b/HW3/MyThreadPool/IMyTask.cs @@ -0,0 +1,34 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyThreadPool; + +/// +/// Defines a contract for a task in the custom thread pool. +/// +/// The type of the result produced by the task. +public interface IMyTask +{ + /// + /// Gets a value indicating whether returns true if the task is completed (successfully or with an error). + /// + bool IsCompleted { get; } + + /// + /// Gets the result of the task. + /// If the task is not completed, it blocks the calling thread until it is completed. + /// If the task completes with an exception, it throws an AggregateException with an internal exception. + /// + TResult Result { get; } + + /// + /// Creates a new task that runs after the current one is completed, + /// using its result as an argument for continuation. + /// A new task is placed in the pool and does not block the calling thread. + /// \ + /// The type of the result produced by the continuation task. + /// A function that takes the result of the current task and produces a new result. + /// A new task representing the continuation. + IMyTask ContinueWith(Func continuation); +} \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.cs b/HW3/MyThreadPool/MyThreadPool.cs new file mode 100644 index 0000000..af59930 --- /dev/null +++ b/HW3/MyThreadPool/MyThreadPool.cs @@ -0,0 +1,13 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyThreadPool; + +/// +/// Main thread pool class +/// +public class MyThreadPool +{ + +} \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.csproj b/HW3/MyThreadPool/MyThreadPool.csproj new file mode 100644 index 0000000..0e53da3 --- /dev/null +++ b/HW3/MyThreadPool/MyThreadPool.csproj @@ -0,0 +1,22 @@ + + + + Exe + net8.0 + enable + enable + MyThreadPool + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + diff --git a/HW3/threadPool/stylecop.json b/HW3/MyThreadPool/stylecop.json similarity index 89% rename from HW3/threadPool/stylecop.json rename to HW3/MyThreadPool/stylecop.json index 76c8e76..a97d030 100644 --- a/HW3/threadPool/stylecop.json +++ b/HW3/MyThreadPool/stylecop.json @@ -3,7 +3,8 @@ "settings": { "documentationRules": { "companyName": "khusainovilas", - "copyrightText": "Copyright (c) {companyName}. All rights reserved." + "copyrightText": "Copyright (c) {companyName}. All rights reserved.", + "xmlHeader": true } } } \ No newline at end of file diff --git a/HW3/threadPool/threadPool.csproj b/HW3/threadPool/threadPool.csproj deleted file mode 100644 index 806b616..0000000 --- a/HW3/threadPool/threadPool.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Exe - net9.0 - enable - enable - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - From 1191c38bf47c61dc5dd45746766828a6687c1fec Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 13 Oct 2025 22:49:27 +0300 Subject: [PATCH 3/7] add MyTask class realization --- HW3/MyThreadPool/MyTask.cs | 119 +++++++++++++++++++++++++++ HW3/MyThreadPool/MyThreadPool.cs | 4 +- HW3/MyThreadPool/MyThreadPool.csproj | 4 + 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 HW3/MyThreadPool/MyTask.cs diff --git a/HW3/MyThreadPool/MyTask.cs b/HW3/MyThreadPool/MyTask.cs new file mode 100644 index 0000000..132cf84 --- /dev/null +++ b/HW3/MyThreadPool/MyTask.cs @@ -0,0 +1,119 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyThreadPool; + +internal class MyTask : IMyTask +{ + private readonly object @lock = new(); + private readonly ManualResetEvent waitHandle = new(false); + private readonly MyThreadPool pool; + private readonly Func func; + private TResult result = default!; + private Exception exception = null!; + private volatile bool isCompleted; + private List? continuations; + + /// + /// Initializes a new instance of the class. + /// + /// The thread pool to queue continuations. + /// The function to execute to produce the result. + public MyTask(MyThreadPool pool, Func func) + { + this.pool = pool ?? throw new ArgumentNullException(nameof(pool)); + this.func = func ?? throw new ArgumentNullException(nameof(func)); + this.continuations = []; + } + + /// + public bool IsCompleted => this.isCompleted; + + /// + public TResult Result + { + get + { + if (!this.isCompleted) + { + this.waitHandle.WaitOne(); + } + + lock (this.@lock) + { + if (this.exception != null) + { + throw new AggregateException("Task failed with an exception.", this.exception); + } + + return this.result; + } + } + } + + /// + public IMyTask ContinueWith(Func continuation) + { + ArgumentNullException.ThrowIfNull(continuation); + + var newTask = new MyTask(this.pool, () => continuation(this.Result)); + lock (this.@lock) + { + if (this.isCompleted) + { + this.pool.QueueTask(newTask.GetExecuteAction()); + } + else + { + if (this.continuations == null) + { + throw new InvalidOperationException("Cannot add continuation to a completed task with cleared continuations."); + } + + this.continuations.Add(newTask.GetExecuteAction()); + } + } + + return newTask; + } + + /// + /// Returns an Action that executes the task, stores the result or exception, and queues continuations. + /// + /// An Action to be executed by the thread pool. + private Action GetExecuteAction() + { + return () => + { + try + { + this.result = this.func(); + } + catch (Exception ex) + { + lock (this.@lock) + { + this.exception = ex; + } + } + finally + { + lock (this.@lock) + { + this.isCompleted = true; + this.waitHandle.Set(); + if (this.continuations != null) + { + foreach (var continuation in this.continuations) + { + this.pool.QueueTask(continuation); + } + } + + this.continuations = null; + } + } + }; + } +} \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.cs b/HW3/MyThreadPool/MyThreadPool.cs index af59930..64282be 100644 --- a/HW3/MyThreadPool/MyThreadPool.cs +++ b/HW3/MyThreadPool/MyThreadPool.cs @@ -9,5 +9,7 @@ namespace MyThreadPool; /// public class MyThreadPool { - + public void QueueTask(Action action) + { + } } \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.csproj b/HW3/MyThreadPool/MyThreadPool.csproj index 0e53da3..9b946ab 100644 --- a/HW3/MyThreadPool/MyThreadPool.csproj +++ b/HW3/MyThreadPool/MyThreadPool.csproj @@ -19,4 +19,8 @@ + + + + From adf377a2dde56cf31eafea118fc433137e204e22 Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 13 Oct 2025 23:05:05 +0300 Subject: [PATCH 4/7] add MyThreadPool class realization --- HW3/MyThreadPool/MyTask.cs | 6 +- HW3/MyThreadPool/MyThreadPool.cs | 149 ++++++++++++++++++++++++++- HW3/MyThreadPool/MyThreadPool.csproj | 2 +- 3 files changed, 153 insertions(+), 4 deletions(-) diff --git a/HW3/MyThreadPool/MyTask.cs b/HW3/MyThreadPool/MyTask.cs index 132cf84..569cf73 100644 --- a/HW3/MyThreadPool/MyTask.cs +++ b/HW3/MyThreadPool/MyTask.cs @@ -4,6 +4,10 @@ namespace MyThreadPool; +/// +/// Represents a task that executes a function and produces a result>. +/// +/// The type of the result produced by the task. internal class MyTask : IMyTask { private readonly object @lock = new(); @@ -82,7 +86,7 @@ public IMyTask ContinueWith(Func co /// Returns an Action that executes the task, stores the result or exception, and queues continuations. /// /// An Action to be executed by the thread pool. - private Action GetExecuteAction() + public Action? GetExecuteAction() { return () => { diff --git a/HW3/MyThreadPool/MyThreadPool.cs b/HW3/MyThreadPool/MyThreadPool.cs index 64282be..371719c 100644 --- a/HW3/MyThreadPool/MyThreadPool.cs +++ b/HW3/MyThreadPool/MyThreadPool.cs @@ -5,11 +5,156 @@ namespace MyThreadPool; /// -/// Main thread pool class +/// Main thread pool class. /// public class MyThreadPool { - public void QueueTask(Action action) + private readonly ManualResetEvent shutdownEvent; + private readonly Thread[] threads; + private readonly Queue taskQueue; + private readonly object queueLock; + private int threadCount; + private volatile bool isShutdown; + + /// + /// Initializes a new instance of the class. + /// + /// The number of threads in the pool. Must be positive. + public MyThreadPool(int threadCount) + { + if (threadCount <= 0) + { + throw new ArgumentOutOfRangeException(nameof(threadCount), "Thread count must be positive."); + } + + this.threadCount = threadCount; + this.threads = new Thread[threadCount]; + this.taskQueue = new Queue(); + this.queueLock = new object(); + this.isShutdown = false; + this.shutdownEvent = new ManualResetEvent(false); + + for (var i = 0; i < threadCount; i++) + { + this.threads[i] = new Thread(this.ThreadProc) + { + IsBackground = true, + Name = $"ThreadPoolThread-{i}", + }; + this.threads[i].Start(); + } + } + + /// + /// Submits a task to the thread pool for execution. + /// + /// The type of the result produced by the task. + /// The function to execute to produce the result. + /// An representing the task. + public IMyTask Submit(Func func) + { + if (this.isShutdown) + { + throw new InvalidOperationException("Cannot submit tasks to a shutdown thread pool."); + } + + var task = new MyTask(this, func); + this.QueueTask(task.GetExecuteAction() ?? throw new InvalidOperationException()); + return task; + } + + /// + /// Queues a task for execution by the thread pool. + /// + /// The action to execute. + /// Thrown when the thread pool is shutting down. + internal void QueueTask(Action action) + { + lock (this.queueLock) + { + if (this.isShutdown) + { + throw new InvalidOperationException("Cannot queue tasks to a shutdown thread pool."); + } + + this.taskQueue.Enqueue(action); + + Monitor.PulseAll(this.queueLock); + } + } + + /// + /// Worker thread procedure that processes tasks from the queue. + /// + private void ThreadProc() + { + while (true) + { + Action task = null!; + lock (this.queueLock) + { + while (this.taskQueue.Count == 0 && !this.isShutdown) + { + Monitor.Wait(this.queueLock); + } + + if (this.isShutdown && this.taskQueue.Count == 0) + { + break; + } + + if (this.taskQueue.Count > 0) + { + task = this.taskQueue.Dequeue(); + } + } + + try + { + task(); + } + catch + { + // ignored + } + } + + if (Interlocked.Decrement(ref this.threadCount) == 0) + { + this.shutdownEvent.Set(); + } + } + + /// + /// Initiates a collaborative shutdown, preventing new tasks from being queued and allowing existing tasks to complete. + /// Blocks until all threads have finished. + /// + public void Shutdown() { + lock (this.queueLock) + { + if (this.isShutdown) + { + return; + } + + this.isShutdown = true; + Monitor.PulseAll(this.queueLock); + } + + this.shutdownEvent.WaitOne(); + } + + /// + /// Disposes the thread pool, ensuring a proper shutdown. + /// + public void Dispose() + { + if (!this.isShutdown) + { + this.Shutdown(); + } + + this.shutdownEvent.Dispose(); } } \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.csproj b/HW3/MyThreadPool/MyThreadPool.csproj index 9b946ab..818c49c 100644 --- a/HW3/MyThreadPool/MyThreadPool.csproj +++ b/HW3/MyThreadPool/MyThreadPool.csproj @@ -1,7 +1,7 @@  - Exe + Library net8.0 enable enable From 4531fe65ff83da1550b70d086089ef247f9a8e21 Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 20 Oct 2025 20:39:30 +0300 Subject: [PATCH 5/7] add nunit tests for mythreadpool --- HW3/HW3.sln | 6 + .../MyThreadPool.Test.csproj | 39 ++++++ HW3/MyThreadPool.Test/MyThreadPoolTest.cs | 131 ++++++++++++++++++ HW3/MyThreadPool.Test/stylecop.json | 10 ++ HW3/MyThreadPool/MyTask.cs | 2 +- 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 HW3/MyThreadPool.Test/MyThreadPool.Test.csproj create mode 100644 HW3/MyThreadPool.Test/MyThreadPoolTest.cs create mode 100644 HW3/MyThreadPool.Test/stylecop.json diff --git a/HW3/HW3.sln b/HW3/HW3.sln index 71535c8..d63f488 100644 --- a/HW3/HW3.sln +++ b/HW3/HW3.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool", "MyThreadPool\MyThreadPool.csproj", "{FA31B85A-23F0-4566-8D57-08FA33575C42}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool.Test", "MyThreadPool.Test\MyThreadPool.Test.csproj", "{0655F283-5458-481F-83B3-F5091360DA57}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {FA31B85A-23F0-4566-8D57-08FA33575C42}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA31B85A-23F0-4566-8D57-08FA33575C42}.Release|Any CPU.ActiveCfg = Release|Any CPU {FA31B85A-23F0-4566-8D57-08FA33575C42}.Release|Any CPU.Build.0 = Release|Any CPU + {0655F283-5458-481F-83B3-F5091360DA57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0655F283-5458-481F-83B3-F5091360DA57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0655F283-5458-481F-83B3-F5091360DA57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0655F283-5458-481F-83B3-F5091360DA57}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj new file mode 100644 index 0000000..8f2c6a7 --- /dev/null +++ b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj @@ -0,0 +1,39 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/HW3/MyThreadPool.Test/MyThreadPoolTest.cs b/HW3/MyThreadPool.Test/MyThreadPoolTest.cs new file mode 100644 index 0000000..1fa7b82 --- /dev/null +++ b/HW3/MyThreadPool.Test/MyThreadPoolTest.cs @@ -0,0 +1,131 @@ +// +// Copyright (c) khusainovilas. All rights reserved. +// + +namespace MyThreadPool.Test; + +using System.Diagnostics; + +/// +/// Unit tests for MyThreadPool. +/// +public class MyThreadPoolTest +{ + /// + /// Tests that submitting a simple task returns the correct result and completes. + /// + [Test] + public void MyThreadPool_Submit_ReturnsCorrectResult() + { + var pool = new MyThreadPool(1); + var task = pool.Submit(() => 42); + Assert.Multiple(() => + { + Assert.That(task.Result, Is.EqualTo(42)); + Assert.That(task.IsCompleted, Is.True); + }); + } + + /// + /// Tests that a continuation task executes correctly with the transformed result. + /// + [Test] + public void IMyTask_ContinueWith_ExecutesCorrectly() + { + var pool = new MyThreadPool(1); + var task = pool.Submit(() => 2 * 2); + var continuation = task.ContinueWith(x => x.ToString()); + Assert.Multiple(() => + { + Assert.That(continuation.Result, Is.EqualTo("4")); + Assert.That(continuation.IsCompleted, Is.True); + }); + } + + /// + /// Tests that an exception in a task is wrapped in AggregateException and the task completes. + /// + [Test] + public void IMyTask_Result_ThrowsAggregateExceptionOnError() + { + var pool = new MyThreadPool(1); + var task = pool.Submit(() => throw new InvalidOperationException("Test error")); + var exception = Assert.Throws(() => _ = task.Result); + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.Multiple(() => + { + Assert.That(exception.InnerException.Message, Is.EqualTo("Test error")); + Assert.That(task.IsCompleted, Is.True); + }); + } + + /// + /// Tests that multiple continuations for a single task execute correctly with different transformations. + /// + [Test] + public void IMyTask_ContinueWith_SupportsMultipleContinuations() + { + var pool = new MyThreadPool(1); + var task = pool.Submit(() => 5); + var cont1 = task.ContinueWith(x => x + 1); + var cont2 = task.ContinueWith(x => x * 2); + Assert.Multiple(() => + { + Assert.That(cont1.Result, Is.EqualTo(6)); + Assert.That(cont2.Result, Is.EqualTo(10)); + Assert.That(cont1.IsCompleted, Is.True); + Assert.That(cont2.IsCompleted, Is.True); + }); + } + + /// + /// Tests that shutdown prevents new tasks and allows existing tasks to complete. + /// + [Test] + public void MyThreadPool_Shutdown_PreventsNewTasksAndCompletesExisting() + { + var pool = new MyThreadPool(1); + var task = pool.Submit(() => + { + Thread.Sleep(100); + return 1; + }); + pool.Shutdown(); + Assert.Throws(() => pool.Submit(() => 2)); + Assert.Multiple(() => + { + Assert.That(task.Result, Is.EqualTo(1)); + Assert.That(task.IsCompleted, Is.True); + }); + } + + /// + /// Tests that the thread pool uses at least n threads by checking parallel execution time. + /// + [Test] + public void MyThreadPool_ThreadCount_UsesAtLeastNThreads() + { + const int n = 4; + var pool = new MyThreadPool(n); + var tasks = new List>(); + var stopwatch = Stopwatch.StartNew(); + for (var i = 0; i < n; i++) + { + tasks.Add(pool.Submit(() => + { + Thread.Sleep(1000); + return 1; + })); + } + + foreach (var task in tasks) + { + Assert.That(task.Result, Is.EqualTo(1)); + } + + stopwatch.Stop(); + + // The work of 4 threads will take approximately 1 second. + Assert.That(stopwatch.Elapsed.TotalSeconds, Is.LessThan(1.5)); + } +} \ No newline at end of file diff --git a/HW3/MyThreadPool.Test/stylecop.json b/HW3/MyThreadPool.Test/stylecop.json new file mode 100644 index 0000000..a97d030 --- /dev/null +++ b/HW3/MyThreadPool.Test/stylecop.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "khusainovilas", + "copyrightText": "Copyright (c) {companyName}. All rights reserved.", + "xmlHeader": true + } + } +} \ No newline at end of file diff --git a/HW3/MyThreadPool/MyTask.cs b/HW3/MyThreadPool/MyTask.cs index 569cf73..577fbcf 100644 --- a/HW3/MyThreadPool/MyTask.cs +++ b/HW3/MyThreadPool/MyTask.cs @@ -86,7 +86,7 @@ public IMyTask ContinueWith(Func co /// Returns an Action that executes the task, stores the result or exception, and queues continuations. /// /// An Action to be executed by the thread pool. - public Action? GetExecuteAction() + public Action GetExecuteAction() { return () => { From 45c0a77dd81dfa25ef57e83906a844bdb99899fc Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Mon, 20 Oct 2025 20:50:05 +0300 Subject: [PATCH 6/7] fix stylecop warning --- .../MyThreadPool.Test.csproj | 2 +- HW3/MyThreadPool/MyThreadPool.cs | 66 +++++++++---------- HW3/MyThreadPool/MyThreadPool.csproj | 13 ++-- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj index 8f2c6a7..b28c8ba 100644 --- a/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj +++ b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - + true false true diff --git a/HW3/MyThreadPool/MyThreadPool.cs b/HW3/MyThreadPool/MyThreadPool.cs index 371719c..790b734 100644 --- a/HW3/MyThreadPool/MyThreadPool.cs +++ b/HW3/MyThreadPool/MyThreadPool.cs @@ -63,6 +63,39 @@ public IMyTask Submit(Func func) return task; } + /// + /// Initiates a collaborative shutdown, preventing new tasks from being queued and allowing existing tasks to complete. + /// Blocks until all threads have finished. + /// + public void Shutdown() + { + lock (this.queueLock) + { + if (this.isShutdown) + { + return; + } + + this.isShutdown = true; + Monitor.PulseAll(this.queueLock); + } + + this.shutdownEvent.WaitOne(); + } + + /// + /// Disposes the thread pool, ensuring a proper shutdown. + /// + public void Dispose() + { + if (!this.isShutdown) + { + this.Shutdown(); + } + + this.shutdownEvent.Dispose(); + } + /// /// Queues a task for execution by the thread pool. /// @@ -124,37 +157,4 @@ private void ThreadProc() this.shutdownEvent.Set(); } } - - /// - /// Initiates a collaborative shutdown, preventing new tasks from being queued and allowing existing tasks to complete. - /// Blocks until all threads have finished. - /// - public void Shutdown() - { - lock (this.queueLock) - { - if (this.isShutdown) - { - return; - } - - this.isShutdown = true; - Monitor.PulseAll(this.queueLock); - } - - this.shutdownEvent.WaitOne(); - } - - /// - /// Disposes the thread pool, ensuring a proper shutdown. - /// - public void Dispose() - { - if (!this.isShutdown) - { - this.Shutdown(); - } - - this.shutdownEvent.Dispose(); - } } \ No newline at end of file diff --git a/HW3/MyThreadPool/MyThreadPool.csproj b/HW3/MyThreadPool/MyThreadPool.csproj index 818c49c..f2ac4a2 100644 --- a/HW3/MyThreadPool/MyThreadPool.csproj +++ b/HW3/MyThreadPool/MyThreadPool.csproj @@ -6,6 +6,7 @@ enable enable MyThreadPool + true @@ -13,14 +14,10 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + From cfd553a2681a73136be6461ebc6b5ec4597837ff Mon Sep 17 00:00:00 2001 From: khusainovilas Date: Tue, 21 Oct 2025 20:47:41 +0300 Subject: [PATCH 7/7] Upgrade project to .NET 9 --- HW3/MyThreadPool.Test/MyThreadPool.Test.csproj | 2 +- HW3/MyThreadPool/MyThreadPool.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj index b28c8ba..5af5968 100644 --- a/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj +++ b/HW3/MyThreadPool.Test/MyThreadPool.Test.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable true diff --git a/HW3/MyThreadPool/MyThreadPool.csproj b/HW3/MyThreadPool/MyThreadPool.csproj index f2ac4a2..6b0dd10 100644 --- a/HW3/MyThreadPool/MyThreadPool.csproj +++ b/HW3/MyThreadPool/MyThreadPool.csproj @@ -2,7 +2,7 @@ Library - net8.0 + net9.0 enable enable MyThreadPool