From 3993c240bc1e2d00a11816cb6fd87947d8c7a4ab Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Sat, 17 Sep 2022 15:09:55 +0300 Subject: [PATCH 01/19] Added gitingore --- .gitignore | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..775497a --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Common IntelliJ Platform excludes + +# User specific +**/.idea/**/workspace.xml +**/.idea/**/tasks.xml +**/.idea/shelf/* +**/.idea/dictionaries +**/.idea/httpRequests/ + +# Sensitive or high-churn files +**/.idea/**/dataSources/ +**/.idea/**/dataSources.ids +**/.idea/**/dataSources.xml +**/.idea/**/dataSources.local.xml +**/.idea/**/sqlDataSources.xml +**/.idea/**/dynamic.xml + +# Rider +# Rider auto-generates .iml files, and contentModel.xml +**/.idea/**/*.iml +**/.idea/**/contentModel.xml +**/.idea/**/modules.xml + +*.suo +*.user +.vs/ +[Bb]in/ +[Oo]bj/ +_UpgradeReport_Files/ +[Pp]ackages/ + +Thumbs.db +Desktop.ini +.DS_Store + +**/.idea/ From 215035901e3e16bbc233f0701d8e88ed3f5be27f Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Wed, 30 Nov 2022 20:05:34 +0300 Subject: [PATCH 02/19] Created project, created MyThreadPool class --- .../MyThreadPool/MyThreadPool.sln | 16 ++++++++++++ .../MyThreadPool/BadThreadsNumberException.cs | 6 +++++ .../MyThreadPool/MyThreadPool/IMyTask.cs | 8 ++++++ .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 26 +++++++++++++++++++ .../MyThreadPool/MyThreadPool.csproj | 9 +++++++ 5 files changed, 65 insertions(+) create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool.sln create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.sln b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln new file mode 100644 index 0000000..9fa5490 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool", "MyThreadPool\MyThreadPool.csproj", "{224B1961-604D-4EAB-ACCA-1D44E285FCDA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs new file mode 100644 index 0000000..5330df9 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs @@ -0,0 +1,6 @@ +namespace MyThreadPool; + +public class BadThreadsNumberException : Exception +{ + +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs new file mode 100644 index 0000000..83ad987 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs @@ -0,0 +1,8 @@ +namespace MyThreadPool; + +public interface IMyTask +{ + public bool IsCompleted { get; } + public TResult Result { get; } + +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs new file mode 100644 index 0000000..033c82c --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -0,0 +1,26 @@ +using System.Collections.Concurrent; + +namespace MyThreadPool; + +/// +/// Pool of tasks +/// +public class MyThreadPool +{ + private ConcurrentQueue> _tasks; + + public int ThreadsNumber { get; } + + public MyThreadPool(int threadsNumber) + { + if (threadsNumber <= 0) + { + throw new BadThreadsNumberException(); + } + + ThreadsNumber = threadsNumber; + _tasks = new ConcurrentQueue>(); + } + + +} diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj new file mode 100644 index 0000000..eb2460e --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + From 1838e3e4c972805fb427eac9746a2fb91385351a Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Wed, 30 Nov 2022 20:07:13 +0300 Subject: [PATCH 03/19] Added NUnit project --- .../MyThreadPool.Tests.csproj | 17 +++++++++++++++++ .../MyThreadPool.Tests/UnitTest1.cs | 17 +++++++++++++++++ 3Homework12.10.22/MyThreadPool/MyThreadPool.sln | 6 ++++++ 3 files changed, 40 insertions(+) create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj new file mode 100644 index 0000000..65a4f7b --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + + false + + + + + + + + + + diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs new file mode 100644 index 0000000..63ff53e --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs @@ -0,0 +1,17 @@ +using NUnit.Framework; + +namespace MyThreadPool.Tests; + +public class Tests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.sln b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln index 9fa5490..f81f778 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.sln +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool", "MyThreadPool\MyThreadPool.csproj", "{224B1961-604D-4EAB-ACCA-1D44E285FCDA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool.Tests", "MyThreadPool.Tests\MyThreadPool.Tests.csproj", "{F948F284-F2E1-4BC4-BC8B-DA89906D74AF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Debug|Any CPU.Build.0 = Debug|Any CPU {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Release|Any CPU.ActiveCfg = Release|Any CPU {224B1961-604D-4EAB-ACCA-1D44E285FCDA}.Release|Any CPU.Build.0 = Release|Any CPU + {F948F284-F2E1-4BC4-BC8B-DA89906D74AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F948F284-F2E1-4BC4-BC8B-DA89906D74AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F948F284-F2E1-4BC4-BC8B-DA89906D74AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F948F284-F2E1-4BC4-BC8B-DA89906D74AF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal From 826a1f6c60e0ff3507646d89c956c00804d6c2ea Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Mon, 26 Dec 2022 18:04:14 +0300 Subject: [PATCH 04/19] Added myThreadClass --- .../MyThreadPool/MyThreadPool/IMyTask.cs | 10 +++- .../MyThreadPool/MyThreadPool/MyTask.cs | 19 +++++++ .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 54 ++++++++++++++++--- 3 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs index 83ad987..89a5b6d 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs @@ -1,8 +1,14 @@ namespace MyThreadPool; +/// +/// An operation performed on MyThreadPool that returns a value +/// +/// public interface IMyTask { - public bool IsCompleted { get; } - public TResult Result { get; } + bool IsCompleted { get; } + TResult Result { get; } + + IMyTask ContinueWith(Func func); } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs new file mode 100644 index 0000000..b8340c8 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -0,0 +1,19 @@ +namespace MyThreadPool; + +public class MyTask : IMyTask +{ + private bool _isComplited = false; + public bool IsCompleted => _isComplited; + + public T Result { get; } + + public MyTask(Func func) + { + + } + + public IMyTask ContinueWith(Func func) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 033c82c..a5fe194 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -7,20 +7,58 @@ namespace MyThreadPool; /// public class MyThreadPool { - private ConcurrentQueue> _tasks; + private BlockingCollection _tasks; + private MyThread[] _myThreads; + private CancellationTokenSource _source = new (); + private bool _isShutdown = false; - public int ThreadsNumber { get; } + public int ThreadCount { get; } - public MyThreadPool(int threadsNumber) + public MyThreadPool(int threadCount = 10) { - if (threadsNumber <= 0) + if (threadCount <= 0) { throw new BadThreadsNumberException(); } - ThreadsNumber = threadsNumber; - _tasks = new ConcurrentQueue>(); + ThreadCount = threadCount; + _tasks = new (); + _myThreads = new MyThread[threadCount]; + + for (int i = 0; i < threadCount; ++i) + { + _myThreads[i] = new MyThread(_tasks, _source.Token); + } + } + + public IMyTask Submit(Func func) + { + var task = new MyTask(func); + return null; + } + + public void Shutdown() + { + if (_isShutdown) + { + return; + } + _tasks.CompleteAdding(); + _source.Cancel(); + } + + private class MyThread + { + private Thread _thread; + private BlockingCollection _collection; + + public MyThread(BlockingCollection collection, CancellationToken token) + { + _collection = collection; + } + + public bool IsWaiting { get; private set; } + + public void Join() => _thread.Join(); } - - } From 6ae9ecf9afef73a395bc97df623087755737fecf Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Mon, 26 Dec 2022 20:37:38 +0300 Subject: [PATCH 05/19] Added comments --- .../MyThreadPool.Tests.csproj | 12 ++- .../MyThreadPool.Tests/UnitTest1.cs | 4 +- .../MyThreadPool/BadThreadsNumberException.cs | 6 -- .../MyThreadPool/MyThreadPool/IMyTask.cs | 18 +++- .../MyThreadPool/MyThreadPool/MyTask.cs | 10 +- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 98 ++++++++++++++----- .../MyThreadPool/MyThreadPool.csproj | 7 ++ 7 files changed, 112 insertions(+), 43 deletions(-) delete mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj index 65a4f7b..d7efcd9 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj @@ -8,10 +8,14 @@ - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs index 63ff53e..818d46c 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs @@ -1,7 +1,7 @@ -using NUnit.Framework; - namespace MyThreadPool.Tests; +using NUnit.Framework; + public class Tests { [SetUp] diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs deleted file mode 100644 index 5330df9..0000000 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/BadThreadsNumberException.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyThreadPool; - -public class BadThreadsNumberException : Exception -{ - -} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs index 89a5b6d..71a3407 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs @@ -1,14 +1,26 @@ namespace MyThreadPool; /// -/// An operation performed on MyThreadPool that returns a value +/// An operation performed on MyThreadPool that returns a value. /// -/// +/// Return value type of task function. public interface IMyTask { + /// + /// Gets a value indicating whether the task result is ready. + /// bool IsCompleted { get; } - + + /// + /// Gets the task result. + /// TResult Result { get; } + /// + /// Creates a new task based on this task. + /// + /// A calculation to make. + /// Type of the resulting value. + /// Task with new resulting value. IMyTask ContinueWith(Func func); } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs index b8340c8..976cea8 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -2,12 +2,16 @@ namespace MyThreadPool; public class MyTask : IMyTask { - private bool _isComplited = false; - public bool IsCompleted => _isComplited; + public bool IsCompleted { get; } = false; public T Result { get; } - public MyTask(Func func) + public MyTask(Func func, MyThreadPool threadPool) + { + + } + + public void Start() { } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index a5fe194..5e9c4d4 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -1,64 +1,112 @@ -using System.Collections.Concurrent; +namespace MyThreadPool; -namespace MyThreadPool; +using System.Collections.Concurrent; /// -/// Pool of tasks +/// Implements the ThreadPool abstraction. /// public class MyThreadPool { - private BlockingCollection _tasks; - private MyThread[] _myThreads; - private CancellationTokenSource _source = new (); - private bool _isShutdown = false; + private BlockingCollection tasks; + private MyThread[] threads; + private CancellationTokenSource source = new(); + private bool isShutdown = false; + private ManualResetEvent reset = new(false); - public int ThreadCount { get; } + /// + /// Gets number of existing threads. + /// + public int ThreadCount { get; } + /// + /// Initializes a new instance of the class. + /// + /// Number of this ThreadPool threads. public MyThreadPool(int threadCount = 10) { if (threadCount <= 0) { - throw new BadThreadsNumberException(); + throw new InvalidDataException(); } - - ThreadCount = threadCount; - _tasks = new (); - _myThreads = new MyThread[threadCount]; - + + this.ThreadCount = threadCount; + this.tasks = new(); + this.threads = new MyThread[threadCount]; + for (int i = 0; i < threadCount; ++i) { - _myThreads[i] = new MyThread(_tasks, _source.Token); + this.threads[i] = new MyThread(this.tasks, this.source.Token); } } + /// + /// Submits new task to the ThreadPool. + /// + /// A calculation to perform. + /// Value type. + /// Task. public IMyTask Submit(Func func) { - var task = new MyTask(func); - return null; + var task = new MyTask(func, this); + this.tasks.Add(() => task.Start()); + return task; } + /// + /// Completes the threads. + /// public void Shutdown() { - if (_isShutdown) + if (this.isShutdown) { return; } - _tasks.CompleteAdding(); - _source.Cancel(); + + this.tasks.CompleteAdding(); + + while (this.tasks.Count > 0) + { + } + + this.source.Cancel(); + foreach (var thread in this.threads) + { + thread.Join(); + if (thread.IsWorking) + { + this.reset.WaitOne(); + } + + thread.Join(); + } } private class MyThread { - private Thread _thread; - private BlockingCollection _collection; + private Thread thread; + private BlockingCollection collection; + + public bool IsWorking { get; private set; } public MyThread(BlockingCollection collection, CancellationToken token) { - _collection = collection; + this.collection = collection; + this.thread = new Thread(() => this.Start(token)); + this.IsWorking = false; } - public bool IsWaiting { get; private set; } + public void Join() => this.thread.Join(); - public void Join() => _thread.Join(); + private void Start(CancellationToken token) + { + while (!token.IsCancellationRequested) + { + if (this.collection.TryTake(out var action)) + { + this.IsWorking = true; + action(); + } + } + } } } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj index eb2460e..226575e 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj @@ -6,4 +6,11 @@ enable + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + From cb67db85e22c85f805d06a7670320d82490b3123 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Mon, 26 Dec 2022 22:17:16 +0300 Subject: [PATCH 06/19] MyThreadPool is done --- .../MyThreadPool/MyThreadPool/IMyTask.cs | 10 +++++----- .../MyThreadPool/MyThreadPool/MyTask.cs | 14 ++++++++++++-- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 17 +++++++++++------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs index 71a3407..2350dab 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs @@ -3,11 +3,11 @@ namespace MyThreadPool; /// /// An operation performed on MyThreadPool that returns a value. /// -/// Return value type of task function. +/// Type of the returnable value. public interface IMyTask { /// - /// Gets a value indicating whether the task result is ready. + /// Get true if the task is completed. /// bool IsCompleted { get; } @@ -19,8 +19,8 @@ public interface IMyTask /// /// Creates a new task based on this task. /// - /// A calculation to make. - /// Type of the resulting value. - /// Task with new resulting value. + /// The function to perform. + /// Type of the new returnable value. + /// Task with new returnable value. IMyTask ContinueWith(Func func); } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs index 976cea8..954733a 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -2,13 +2,18 @@ namespace MyThreadPool; public class MyTask : IMyTask { + private MyThreadPool pool; + private Func func; + private readonly ManualResetEvent reset = new(false); + public bool IsCompleted { get; } = false; public T Result { get; } public MyTask(Func func, MyThreadPool threadPool) { - + this.func = func; + this.pool = threadPool; } public void Start() @@ -18,6 +23,11 @@ public void Start() public IMyTask ContinueWith(Func func) { - throw new NotImplementedException(); + if (!this.IsCompleted) + { + this.reset.WaitOne(); + } + + return this.pool.Submit(new Func(() => func(this.Result))); } } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 5e9c4d4..a505070 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -3,7 +3,7 @@ using System.Collections.Concurrent; /// -/// Implements the ThreadPool abstraction. +/// The ThreadPool abstraction. /// public class MyThreadPool { @@ -11,7 +11,6 @@ public class MyThreadPool private MyThread[] threads; private CancellationTokenSource source = new(); private bool isShutdown = false; - private ManualResetEvent reset = new(false); /// /// Gets number of existing threads. @@ -74,10 +73,8 @@ public void Shutdown() thread.Join(); if (thread.IsWorking) { - this.reset.WaitOne(); + throw new TimeoutException(); } - - thread.Join(); } } @@ -85,6 +82,7 @@ private class MyThread { private Thread thread; private BlockingCollection collection; + private int timeout = 10000; public bool IsWorking { get; private set; } @@ -95,7 +93,13 @@ public MyThread(BlockingCollection collection, CancellationToken token) this.IsWorking = false; } - public void Join() => this.thread.Join(); + public void Join() + { + if (this.thread.IsAlive) + { + this.thread.Join(this.timeout); + } + } private void Start(CancellationToken token) { @@ -105,6 +109,7 @@ private void Start(CancellationToken token) { this.IsWorking = true; action(); + this.IsWorking = false; } } } From b5bef33161a804b25608e9dbe424403fa3e107c3 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Mon, 26 Dec 2022 22:39:20 +0300 Subject: [PATCH 07/19] MyTask is done --- .../MyThreadPool/MyThreadPool/MyTask.cs | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs index 954733a..1596505 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -4,11 +4,12 @@ public class MyTask : IMyTask { private MyThreadPool pool; private Func func; - private readonly ManualResetEvent reset = new(false); + private ManualResetEvent reset = new(false); + private T result; + private Exception? retrunedException; - public bool IsCompleted { get; } = false; - - public T Result { get; } + /// + public bool IsCompleted { get; private set; } = false; public MyTask(Func func, MyThreadPool threadPool) { @@ -16,18 +17,46 @@ public MyTask(Func func, MyThreadPool threadPool) this.pool = threadPool; } + /// + public T Result + { + get + { + this.reset.WaitOne(); + if (this.retrunedException != null) + { + throw new AggregateException(this.retrunedException); + } + + return this.result; + } + } + public void Start() { - + try + { + this.pool.Submit(new Func(() => this.func())); + } + catch (Exception exception) + { + this.retrunedException = exception; + } + finally + { + this.reset.Set(); + this.IsCompleted = true; + } } - public IMyTask ContinueWith(Func func) + /// + public IMyTask ContinueWith(Func func1) { if (!this.IsCompleted) { this.reset.WaitOne(); } - return this.pool.Submit(new Func(() => func(this.Result))); + return this.pool.Submit(new Func(() => func1(this.Result))); } } \ No newline at end of file From 76aca303e93be81a7218deb36535a86f86f1ee29 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Tue, 27 Dec 2022 13:03:34 +0300 Subject: [PATCH 08/19] Added comment --- .../{UnitTest1.cs => MyTask.Tests.cs} | 0 .../MyThreadPool.Tests/MyThreadPool.Tests.cs | 6 ++++++ .../MyThreadPool/MyThreadPool/MyTask.cs | 14 ++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) rename 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/{UnitTest1.cs => MyTask.Tests.cs} (100%) create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyTask.Tests.cs similarity index 100% rename from 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/UnitTest1.cs rename to 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyTask.Tests.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs new file mode 100644 index 0000000..cd7f213 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs @@ -0,0 +1,6 @@ +namespace MyThreadPool.Tests; + +public class MyThreadPool_Tests +{ + +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs index 1596505..bfeac13 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -1,16 +1,22 @@ namespace MyThreadPool; +/// public class MyTask : IMyTask { private MyThreadPool pool; private Func func; private ManualResetEvent reset = new(false); private T result; - private Exception? retrunedException; + private Exception? returnedException; /// public bool IsCompleted { get; private set; } = false; + /// + /// Initializes a new instance of the class. + /// + /// Function that will performed. + /// public MyTask(Func func, MyThreadPool threadPool) { this.func = func; @@ -23,9 +29,9 @@ public T Result get { this.reset.WaitOne(); - if (this.retrunedException != null) + if (this.returnedException != null) { - throw new AggregateException(this.retrunedException); + throw new AggregateException(this.returnedException); } return this.result; @@ -40,7 +46,7 @@ public void Start() } catch (Exception exception) { - this.retrunedException = exception; + this.returnedException = exception; } finally { From c7f3fe8db7e853ce8361b011230e6f4b2efb5fbe Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Fri, 10 Feb 2023 16:40:50 +0300 Subject: [PATCH 09/19] Fixed thread pool, added tests --- .../MyThreadPool.Tests/MyThreadPool.Tests.cs | 6 ----- .../MyThreadPool/MyThreadPool.sln | 2 +- .../MyThreadPool/MyThreadPool/IMyTask.cs | 2 +- .../MyThreadPool/MyThreadPool/MyTask.cs | 16 +++++------ .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 24 ++++++++++------- .../MyThreadPool/MyThreadPool.csproj | 7 ----- .../MyTaskTests.cs} | 6 ----- .../MyThreadPoolTests/MyThreadPoolTests.cs | 27 +++++++++++++++++++ .../MyThreadPoolTests.csproj} | 10 ++++--- 9 files changed, 58 insertions(+), 42 deletions(-) delete mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs rename 3Homework12.10.22/MyThreadPool/{MyThreadPool.Tests/MyTask.Tests.cs => MyThreadPoolTests/MyTaskTests.cs} (63%) create mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs rename 3Homework12.10.22/MyThreadPool/{MyThreadPool.Tests/MyThreadPool.Tests.csproj => MyThreadPoolTests/MyThreadPoolTests.csproj} (67%) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs deleted file mode 100644 index cd7f213..0000000 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyThreadPool.Tests; - -public class MyThreadPool_Tests -{ - -} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.sln b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln index f81f778..dd05c0c 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.sln +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool", "MyThreadPool\MyThreadPool.csproj", "{224B1961-604D-4EAB-ACCA-1D44E285FCDA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPool.Tests", "MyThreadPool.Tests\MyThreadPool.Tests.csproj", "{F948F284-F2E1-4BC4-BC8B-DA89906D74AF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyThreadPoolTests", "MyThreadPoolTests\MyThreadPoolTests.csproj", "{F948F284-F2E1-4BC4-BC8B-DA89906D74AF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs index 2350dab..d0b4f13 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/IMyTask.cs @@ -7,7 +7,7 @@ namespace MyThreadPool; public interface IMyTask { /// - /// Get true if the task is completed. + /// Gets a value indicating whether get true if the task is completed. /// bool IsCompleted { get; } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs index bfeac13..8248235 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs @@ -6,23 +6,23 @@ public class MyTask : IMyTask private MyThreadPool pool; private Func func; private ManualResetEvent reset = new(false); - private T result; + private T? result; private Exception? returnedException; - /// - public bool IsCompleted { get; private set; } = false; - /// /// Initializes a new instance of the class. /// /// Function that will performed. - /// + /// Pool for the submit. public MyTask(Func func, MyThreadPool threadPool) { this.func = func; this.pool = threadPool; } + /// + public bool IsCompleted { get; private set; } + /// public T Result { @@ -34,7 +34,7 @@ public T Result throw new AggregateException(this.returnedException); } - return this.result; + return this.result!; } } @@ -42,7 +42,7 @@ public void Start() { try { - this.pool.Submit(new Func(() => this.func())); + this.result = this.func(); } catch (Exception exception) { @@ -63,6 +63,6 @@ public IMyTask ContinueWith(Func func1) this.reset.WaitOne(); } - return this.pool.Submit(new Func(() => func1(this.Result))); + return this.pool.Submit(() => func1(this.Result)); } } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index a505070..5263a48 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -12,11 +12,6 @@ public class MyThreadPool private CancellationTokenSource source = new(); private bool isShutdown = false; - /// - /// Gets number of existing threads. - /// - public int ThreadCount { get; } - /// /// Initializes a new instance of the class. /// @@ -38,6 +33,11 @@ public MyThreadPool(int threadCount = 10) } } + /// + /// Gets number of existing threads. + /// + public int ThreadCount { get; } + /// /// Submits new task to the ThreadPool. /// @@ -73,7 +73,7 @@ public void Shutdown() thread.Join(); if (thread.IsWorking) { - throw new TimeoutException(); + thread.Interrupt(); } } } @@ -82,17 +82,18 @@ private class MyThread { private Thread thread; private BlockingCollection collection; - private int timeout = 10000; - - public bool IsWorking { get; private set; } + private int timeout = 5000; public MyThread(BlockingCollection collection, CancellationToken token) { this.collection = collection; this.thread = new Thread(() => this.Start(token)); this.IsWorking = false; + this.thread.Start(); } + public bool IsWorking { get; private set; } + public void Join() { if (this.thread.IsAlive) @@ -101,6 +102,11 @@ public void Join() } } + public void Interrupt() + { + this.thread.Interrupt(); + } + private void Start(CancellationToken token) { while (!token.IsCancellationRequested) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj index 226575e..eb2460e 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj @@ -6,11 +6,4 @@ enable - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyTask.Tests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs similarity index 63% rename from 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyTask.Tests.cs rename to 3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs index 818d46c..e5a86a3 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyTask.Tests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs @@ -8,10 +8,4 @@ public class Tests public void Setup() { } - - [Test] - public void Test1() - { - Assert.Pass(); - } } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs new file mode 100644 index 0000000..b66e3a1 --- /dev/null +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -0,0 +1,27 @@ +namespace MyThreadPool.Tests; + +using System; + +using NUnit.Framework; + +public class MyThreadPoolTests +{ + [Test] + public void ThreadPoolWorks() + { + var x = new Func(() => + { + return 1; + }); + MyThreadPool pool = new(1); + var myTask = pool.Submit(() => x()); + Assert.AreEqual(1, myTask.Result); + pool.Shutdown(); + } + + [Test] + public void Thread() + { + + } +} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj similarity index 67% rename from 3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj rename to 3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj index d7efcd9..faab430 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool.Tests/MyThreadPool.Tests.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj @@ -5,6 +5,8 @@ enable false + + MyThreadPool.Tests @@ -12,10 +14,10 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + From 6ec01e579cc4ea976a045527d6f4bdaf283f5d7f Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Fri, 10 Feb 2023 17:02:24 +0300 Subject: [PATCH 10/19] Fixed smth --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 7 +++++++ .../MyThreadPool/MyThreadPoolTests/MyTaskTests.cs | 11 ----------- .../MyThreadPoolTests/MyThreadPoolTests.cs | 9 +++++++++ 3 files changed, 16 insertions(+), 11 deletions(-) delete mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 5263a48..8a9b606 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -68,12 +68,19 @@ public void Shutdown() } this.source.Cancel(); + var areJoined = true; foreach (var thread in this.threads) { thread.Join(); if (thread.IsWorking) { thread.Interrupt(); + areJoined = false; + } + + if (!areJoined) + { + throw new TimeoutException(); } } } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs deleted file mode 100644 index e5a86a3..0000000 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyTaskTests.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MyThreadPool.Tests; - -using NUnit.Framework; - -public class Tests -{ - [SetUp] - public void Setup() - { - } -} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs index b66e3a1..5cf96fc 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -6,6 +6,15 @@ namespace MyThreadPool.Tests; public class MyThreadPoolTests { + private int threadsInThreadPoolCount = 10; + private MyThreadPool pool; + + [SetUp] + public void SetUp() + { + pool = new MyThreadPool(threadsInThreadPoolCount); + } + [Test] public void ThreadPoolWorks() { From c98b6bee1ef205545e8c8a59bc5a270a1ae13ccc Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Fri, 10 Feb 2023 17:43:07 +0300 Subject: [PATCH 11/19] MyTask class moved to MyThreadPool class --- .../MyThreadPool/MyThreadPool/MyTask.cs | 68 ------------------- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 67 ++++++++++++++++++ .../MyThreadPoolTests/MyThreadPoolTests.cs | 9 +-- 3 files changed, 68 insertions(+), 76 deletions(-) delete mode 100644 3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs deleted file mode 100644 index 8248235..0000000 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyTask.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace MyThreadPool; - -/// -public class MyTask : IMyTask -{ - private MyThreadPool pool; - private Func func; - private ManualResetEvent reset = new(false); - private T? result; - private Exception? returnedException; - - /// - /// Initializes a new instance of the class. - /// - /// Function that will performed. - /// Pool for the submit. - public MyTask(Func func, MyThreadPool threadPool) - { - this.func = func; - this.pool = threadPool; - } - - /// - public bool IsCompleted { get; private set; } - - /// - public T Result - { - get - { - this.reset.WaitOne(); - if (this.returnedException != null) - { - throw new AggregateException(this.returnedException); - } - - return this.result!; - } - } - - public void Start() - { - try - { - this.result = this.func(); - } - catch (Exception exception) - { - this.returnedException = exception; - } - finally - { - this.reset.Set(); - this.IsCompleted = true; - } - } - - /// - public IMyTask ContinueWith(Func func1) - { - if (!this.IsCompleted) - { - this.reset.WaitOne(); - } - - return this.pool.Submit(() => func1(this.Result)); - } -} \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 8a9b606..68559f6 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -65,6 +65,7 @@ public void Shutdown() while (this.tasks.Count > 0) { + Thread.Sleep(1000); } this.source.Cancel(); @@ -124,7 +125,73 @@ private void Start(CancellationToken token) action(); this.IsWorking = false; } + else + { + Thread.Sleep(1000); + } } } } + + private class MyTask : IMyTask + { + private MyThreadPool pool; + private Func func; + private ManualResetEvent reset = new(false); + private T? result; + private Exception? returnedException; + + /// + /// Initializes a new instance of the class. + /// + /// Function that will performed. + /// Pool for the submit. + public MyTask(Func func, MyThreadPool threadPool) + { + this.func = func; + this.pool = threadPool; + IsCompleted = false; + } + + /// + public bool IsCompleted { get; private set; } + + /// + public T Result + { + get + { + this.reset.WaitOne(); + if (this.returnedException != null) + { + throw new AggregateException(this.returnedException); + } + + return this.result!; + } + } + + public void Start() + { + try + { + this.result = this.func(); + } + catch (Exception exception) + { + this.returnedException = exception; + } + finally + { + this.reset.Set(); + this.IsCompleted = true; + } + } + + /// + public IMyTask ContinueWith(Func func1) + { + return this.pool.Submit(() => func1(this.Result)); + } + } } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs index 5cf96fc..6b0e9e0 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -7,14 +7,7 @@ namespace MyThreadPool.Tests; public class MyThreadPoolTests { private int threadsInThreadPoolCount = 10; - private MyThreadPool pool; - [SetUp] - public void SetUp() - { - pool = new MyThreadPool(threadsInThreadPoolCount); - } - [Test] public void ThreadPoolWorks() { @@ -22,7 +15,7 @@ public void ThreadPoolWorks() { return 1; }); - MyThreadPool pool = new(1); + MyThreadPool pool = new(threadsInThreadPoolCount); var myTask = pool.Submit(() => x()); Assert.AreEqual(1, myTask.Result); pool.Shutdown(); From 5b4d94aacf0b6ca359e3ee368d17df50f256c2ea Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Fri, 10 Feb 2023 19:00:04 +0300 Subject: [PATCH 12/19] Writed tests --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 29 ++-- .../MyThreadPoolTests/MyThreadPoolTests.cs | 146 +++++++++++++++++- 2 files changed, 158 insertions(+), 17 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 68559f6..61fb7e7 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -31,12 +31,19 @@ public MyThreadPool(int threadCount = 10) { this.threads[i] = new MyThread(this.tasks, this.source.Token); } + + isShutdown = false; } /// /// Gets number of existing threads. /// public int ThreadCount { get; } + + /// + /// Gets a value indicating the Shutdown status of the thread pool. + /// + public bool IsShutDown { get; private set; } /// /// Submits new task to the ThreadPool. @@ -63,11 +70,16 @@ public void Shutdown() this.tasks.CompleteAdding(); - while (this.tasks.Count > 0) + for (int i = 0; i < 20 && this.tasks.Count > 0; ++i) { Thread.Sleep(1000); } + if (this.tasks.Count > 0) + { + throw new TimeoutException("Tasks from the queue cannot be executed."); + } + this.source.Cancel(); var areJoined = true; foreach (var thread in this.threads) @@ -75,14 +87,14 @@ public void Shutdown() thread.Join(); if (thread.IsWorking) { - thread.Interrupt(); areJoined = false; } + } - if (!areJoined) - { - throw new TimeoutException(); - } + isShutdown = true; + if (!areJoined) + { + throw new TimeoutException("Not all tasks were accomplished."); } } @@ -110,11 +122,6 @@ public void Join() } } - public void Interrupt() - { - this.thread.Interrupt(); - } - private void Start(CancellationToken token) { while (!token.IsCancellationRequested) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs index 6b0e9e0..02cc82c 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -1,5 +1,9 @@ namespace MyThreadPool.Tests; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + using System; using NUnit.Framework; @@ -7,23 +11,153 @@ namespace MyThreadPool.Tests; public class MyThreadPoolTests { private int threadsInThreadPoolCount = 10; - + [Test] - public void ThreadPoolWorks() + public void AtLeastNThreadsInThePool() { - var x = new Func(() => + MyThreadPool pool = new(threadsInThreadPoolCount); + var func = new Func(() => { + Thread.Sleep(5000); return 1; }); + + var stopwatch = new Stopwatch(); + var tasks = new List>(); + stopwatch.Start(); + for (int i = 0; i < threadsInThreadPoolCount; ++i) + { + tasks.Add(pool.Submit(() => func())); + } + + for (int i = 0; i < threadsInThreadPoolCount; ++i) + { + Assert.AreEqual(1, tasks[i].Result); + } + + stopwatch.Stop(); + Assert.Less(stopwatch.ElapsedMilliseconds, 10000); + + pool.Shutdown(); + } + + [Test] + public void ManyTasksWorks() + { MyThreadPool pool = new(threadsInThreadPoolCount); - var myTask = pool.Submit(() => x()); - Assert.AreEqual(1, myTask.Result); + var func = new Func(() => + { + int x = 0; + for (int i = 1; i < 1000; ++i) + { + x += i; + } + + return x; + }); + + var tasks = new List>(); + for (int i = 0; i < 500; ++i) + { + tasks.Add(pool.Submit(() => func())); + } + + for (int i = 0; i < 500; ++i) + { + Assert.AreEqual(499500, tasks[i].Result); + } + pool.Shutdown(); } + + + [Test] + public void ShutdownWorksWithEndlessProcess() + { + MyThreadPool pool = new(3); + var func = new Func(() => + { + Thread.Sleep(20000); + return 1; + }); + + var tasks = new List>(); + for (int i = 0; i < 2; ++i) + { + tasks.Add(pool.Submit(() => func())); + } + + for (int i = 0; i < 10; ++i) + { + tasks.Add(pool.Submit(() => 2 * 2)); + } + + for (int i = 9; i < 12; ++i) + { + Assert.AreEqual(4, tasks[i].Result); + } + Assert.Catch(pool.Shutdown); + } + [Test] - public void Thread() + public void SeveralContinueWithWorks() { + MyThreadPool pool = new(threadsInThreadPoolCount); + var func1 = new Func(() => + { + Thread.Sleep(500); + return 1; + }); + + var func2 = new Func((x) => + { + Thread.Sleep(500); + return 2 * x; + }); + + var tasks = new List>(); + tasks.Add(pool.Submit(() => func1())); + for (int i = 1; i < 10; ++i) + { + tasks.Add(tasks[i - 1].ContinueWith(func2)); + } + + int x = 1; + for (int i = 0; i < 1; ++i) + { + Assert.AreEqual(x, tasks[i].Result); + x *= 2; + } + + pool.Shutdown(); +} + + [Test] + public void ContinueWithDoesNotBlockThread() + { + MyThreadPool pool = new(3); + var func1 = new Func(() => + { + Thread.Sleep(5000); + return 1; + }); + + var func2 = new Func( x => 2 * x ); + + var stopwatch = new Stopwatch(); + var tasks = new List>(); + stopwatch.Start(); + tasks.Add(pool.Submit(() => func1())); + tasks.Add(tasks[0].ContinueWith(func2)); + tasks.Add(pool.Submit(() => func1())); + Assert.AreEqual(1, tasks[0].Result); + Assert.AreEqual(2, tasks[1].Result); + Assert.AreEqual(1, tasks[2].Result); + stopwatch.Stop(); + Assert.Less(stopwatch.ElapsedMilliseconds, 10000); + + pool.Shutdown(); } } \ No newline at end of file From e35b92fb3bb02c6b8d416c9e2e6682a523523918 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Fri, 10 Feb 2023 19:04:38 +0300 Subject: [PATCH 13/19] Fixed style --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 15 +++---- .../MyThreadPoolTests/MyThreadPoolTests.cs | 40 +++++++++---------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 61fb7e7..9fa9cc8 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -10,7 +10,7 @@ public class MyThreadPool private BlockingCollection tasks; private MyThread[] threads; private CancellationTokenSource source = new(); - private bool isShutdown = false; + private bool isShutdown; /// /// Initializes a new instance of the class. @@ -32,18 +32,13 @@ public MyThreadPool(int threadCount = 10) this.threads[i] = new MyThread(this.tasks, this.source.Token); } - isShutdown = false; + this.isShutdown = false; } /// /// Gets number of existing threads. /// public int ThreadCount { get; } - - /// - /// Gets a value indicating the Shutdown status of the thread pool. - /// - public bool IsShutDown { get; private set; } /// /// Submits new task to the ThreadPool. @@ -91,7 +86,7 @@ public void Shutdown() } } - isShutdown = true; + this.isShutdown = true; if (!areJoined) { throw new TimeoutException("Not all tasks were accomplished."); @@ -139,7 +134,7 @@ private void Start(CancellationToken token) } } } - + private class MyTask : IMyTask { private MyThreadPool pool; @@ -157,7 +152,7 @@ public MyTask(Func func, MyThreadPool threadPool) { this.func = func; this.pool = threadPool; - IsCompleted = false; + this.IsCompleted = false; } /// diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs index 02cc82c..b266e08 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -1,21 +1,19 @@ namespace MyThreadPool.Tests; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; - -using System; - using NUnit.Framework; public class MyThreadPoolTests { private int threadsInThreadPoolCount = 10; - + [Test] public void AtLeastNThreadsInThePool() { - MyThreadPool pool = new(threadsInThreadPoolCount); + MyThreadPool pool = new(this.threadsInThreadPoolCount); var func = new Func(() => { Thread.Sleep(5000); @@ -25,18 +23,19 @@ public void AtLeastNThreadsInThePool() var stopwatch = new Stopwatch(); var tasks = new List>(); stopwatch.Start(); - for (int i = 0; i < threadsInThreadPoolCount; ++i) + for (int i = 0; i < this.threadsInThreadPoolCount; ++i) { tasks.Add(pool.Submit(() => func())); } - for (int i = 0; i < threadsInThreadPoolCount; ++i) + for (int i = 0; i < this.threadsInThreadPoolCount; ++i) { Assert.AreEqual(1, tasks[i].Result); } - + stopwatch.Stop(); Assert.Less(stopwatch.ElapsedMilliseconds, 10000); + Assert.AreEqual(10, pool.ThreadCount); pool.Shutdown(); } @@ -44,7 +43,7 @@ public void AtLeastNThreadsInThePool() [Test] public void ManyTasksWorks() { - MyThreadPool pool = new(threadsInThreadPoolCount); + MyThreadPool pool = new(this.threadsInThreadPoolCount); var func = new Func(() => { int x = 0; @@ -52,10 +51,10 @@ public void ManyTasksWorks() { x += i; } - + return x; }); - + var tasks = new List>(); for (int i = 0; i < 500; ++i) { @@ -69,8 +68,7 @@ public void ManyTasksWorks() pool.Shutdown(); } - - + [Test] public void ShutdownWorksWithEndlessProcess() { @@ -80,13 +78,13 @@ public void ShutdownWorksWithEndlessProcess() Thread.Sleep(20000); return 1; }); - + var tasks = new List>(); for (int i = 0; i < 2; ++i) { tasks.Add(pool.Submit(() => func())); } - + for (int i = 0; i < 10; ++i) { tasks.Add(pool.Submit(() => 2 * 2)); @@ -98,12 +96,12 @@ public void ShutdownWorksWithEndlessProcess() } Assert.Catch(pool.Shutdown); - } - + } + [Test] public void SeveralContinueWithWorks() { - MyThreadPool pool = new(threadsInThreadPoolCount); + MyThreadPool pool = new(this.threadsInThreadPoolCount); var func1 = new Func(() => { Thread.Sleep(500); @@ -142,8 +140,8 @@ public void ContinueWithDoesNotBlockThread() Thread.Sleep(5000); return 1; }); - - var func2 = new Func( x => 2 * x ); + + var func2 = new Func(x => 2 * x); var stopwatch = new Stopwatch(); var tasks = new List>(); @@ -151,7 +149,7 @@ public void ContinueWithDoesNotBlockThread() tasks.Add(pool.Submit(() => func1())); tasks.Add(tasks[0].ContinueWith(func2)); tasks.Add(pool.Submit(() => func1())); - + Assert.AreEqual(1, tasks[0].Result); Assert.AreEqual(2, tasks[1].Result); Assert.AreEqual(1, tasks[2].Result); From 6e4d56987f10ff0c455d2de4fd917e6d2155ba7e Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Sun, 12 Feb 2023 13:43:53 +0300 Subject: [PATCH 14/19] Removed unnecessary 'Sleep' --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 44 ++++++++++++++----- .../MyThreadPool/MyThreadPool.csproj | 7 +++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 9fa9cc8..4aa944a 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -11,6 +11,8 @@ public class MyThreadPool private MyThread[] threads; private CancellationTokenSource source = new(); private bool isShutdown; + private AutoResetEvent tasksOver; + private AutoResetEvent taskAdded; /// /// Initializes a new instance of the class. @@ -26,10 +28,12 @@ public MyThreadPool(int threadCount = 10) this.ThreadCount = threadCount; this.tasks = new(); this.threads = new MyThread[threadCount]; + this.tasksOver = new AutoResetEvent(false); + this.taskAdded = new AutoResetEvent(false); for (int i = 0; i < threadCount; ++i) { - this.threads[i] = new MyThread(this.tasks, this.source.Token); + this.threads[i] = new MyThread(this.tasks, this.source.Token, this.tasksOver, this.taskAdded); } this.isShutdown = false; @@ -50,6 +54,7 @@ public IMyTask Submit(Func func) { var task = new MyTask(func, this); this.tasks.Add(() => task.Start()); + this.taskAdded.Set(); return task; } @@ -64,11 +69,14 @@ public void Shutdown() } this.tasks.CompleteAdding(); - - for (int i = 0; i < 20 && this.tasks.Count > 0; ++i) + var timeoutThread = new Thread(() => { - Thread.Sleep(1000); - } + Thread.Sleep(20000); + this.tasksOver.Set(); + }); + + timeoutThread.Start(); + this.tasksOver.WaitOne(); if (this.tasks.Count > 0) { @@ -76,6 +84,12 @@ public void Shutdown() } this.source.Cancel(); + + for (int i = 0; i < this.ThreadCount; i++) + { + this.taskAdded.Set(); + } + var areJoined = true; foreach (var thread in this.threads) { @@ -98,10 +112,14 @@ private class MyThread private Thread thread; private BlockingCollection collection; private int timeout = 5000; + private AutoResetEvent tasksOver; + private AutoResetEvent taskAdded; - public MyThread(BlockingCollection collection, CancellationToken token) + public MyThread(BlockingCollection collection, CancellationToken token, AutoResetEvent tasksOver, AutoResetEvent taskAdded) { + this.tasksOver = tasksOver; this.collection = collection; + this.taskAdded = taskAdded; this.thread = new Thread(() => this.Start(token)); this.IsWorking = false; this.thread.Start(); @@ -129,7 +147,8 @@ private void Start(CancellationToken token) } else { - Thread.Sleep(1000); + this.tasksOver.Set(); + this.taskAdded.WaitOne(); } } } @@ -138,8 +157,8 @@ private void Start(CancellationToken token) private class MyTask : IMyTask { private MyThreadPool pool; - private Func func; - private ManualResetEvent reset = new(false); + private Func? func; + private ManualResetEvent resetEvent = new(false); private T? result; private Exception? returnedException; @@ -163,7 +182,7 @@ public T Result { get { - this.reset.WaitOne(); + this.resetEvent.WaitOne(); if (this.returnedException != null) { throw new AggregateException(this.returnedException); @@ -177,7 +196,7 @@ public void Start() { try { - this.result = this.func(); + this.result = this.func!(); } catch (Exception exception) { @@ -185,8 +204,9 @@ public void Start() } finally { - this.reset.Set(); + this.func = null; this.IsCompleted = true; + this.resetEvent.Set(); } } diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj index eb2460e..226575e 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj @@ -6,4 +6,11 @@ enable + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + From dd73d8439e9d356670625f7ab1be7d835fc7d4b7 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Sun, 12 Feb 2023 14:35:59 +0300 Subject: [PATCH 15/19] Waiting for the result of the previous action about ContinueWith is moved to a separate thread. --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 4aa944a..1a70daf 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -213,7 +213,16 @@ public void Start() /// public IMyTask ContinueWith(Func func1) { - return this.pool.Submit(() => func1(this.Result)); + TNewResult NewFunc() + { + T realResult = this.Result; + return this.pool.Submit(() => func1(realResult)).Result; + } + + var newTask = new MyTask(NewFunc, this.pool); + var thread = new Thread(() => newTask.Start()); + thread.Start(); + return newTask; } } } From 513bea3c4d861f4c5433cd12a56888124e8ea45a Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Sun, 12 Feb 2023 16:54:54 +0300 Subject: [PATCH 16/19] Added tests --- .../MyThreadPoolTests/MyThreadPoolTests.cs | 115 +++++++++++++++++- .../MyThreadPoolTests.csproj | 4 + 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs index b266e08..c8abeb5 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.cs @@ -4,6 +4,7 @@ namespace MyThreadPool.Tests; using System.Collections.Generic; using System.Diagnostics; using System.Threading; +using System.Threading.Tasks; using NUnit.Framework; public class MyThreadPoolTests @@ -108,7 +109,7 @@ public void SeveralContinueWithWorks() return 1; }); - var func2 = new Func((x) => + var func2 = new Func(x => { Thread.Sleep(500); return 2 * x; @@ -158,4 +159,116 @@ public void ContinueWithDoesNotBlockThread() pool.Shutdown(); } + + [Test] + public async Task ParallelSubmitsWorks() + { + MyThreadPool pool = new(); + var func1 = new Func(() => + { + Thread.Sleep(50); + return 1; + }); + + var tasks = new Task[100]; + for (int i = 0; i < 100; ++i) + { + tasks[i] = Task.Run(() => pool.Submit(() => func1()).Result); + } + + for (int i = 0; i < 100; ++i) + { + Assert.AreEqual(1, await tasks[i]); + } + + pool.Shutdown(); + } + + [Test] + public async Task ParallelSubmitAdnShutDownWorks() + { + MyThreadPool pool = new(); + var func1 = new Func(() => + { + Thread.Sleep(50); + return 1; + }); + + var tasks = new Task[100]; + Task? task1 = null; + for (int i = 0; i < 100; ++i) + { + if (i == 50) + { + task1 = Task.Run(() => pool.Shutdown()); + } + + tasks[i] = Task.Run(() => pool.Submit(() => func1()).Result); + } + + for (int i = 0; i < 100; ++i) + { + int result; + var invalidOperation = new InvalidOperationException().GetType(); + try + { + result = tasks[i].Result; + Assert.AreEqual(1, result); + } + catch (AggregateException e) + { + Assert.AreEqual(1, e.InnerExceptions.Count); + Assert.AreEqual(invalidOperation, e.InnerException!.GetType()); + } + } + + Assert.NotNull(task1); + if (task1 == null) + { + return; + } + + await task1; + Assert.IsNull(task1.Exception); + + pool.Shutdown(); + } + + [Test] + public Task ParallelSubmitsContinueWithAndShutDownWorks() + { + MyThreadPool pool = new(1); + var func1 = new Func(() => + { + Thread.Sleep(50); + return 1; + }); + var func2 = new Func(x => + { + Thread.Sleep(50); + return 2 * x; + }); + + var taskSubmit = Task.Run(() => pool.Submit(() => func1())); + Assert.AreEqual(1, taskSubmit.Result.Result); + var taskShutDown = Task.Run(() => pool.Shutdown()); + var taskContinueWith = Task.Run(() => taskSubmit.Result.ContinueWith(func2)); + + int result; + var invalidOperation = new InvalidOperationException().GetType(); + try + { + result = taskContinueWith.Result.Result; + Assert.AreEqual(2, result); + } + catch (AggregateException e) + { + Assert.AreEqual(1, e.InnerExceptions.Count); + Assert.AreEqual(invalidOperation, e.InnerException!.GetType()); + } + + Assert.IsNull(taskShutDown.Exception); + pool.Shutdown(); + return Task.CompletedTask; + } } \ No newline at end of file diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj index faab430..24a0faa 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj @@ -14,6 +14,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 6deb243a51fb35da8bc2a64ba11cc2acb2a31786 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Sun, 12 Feb 2023 17:00:31 +0300 Subject: [PATCH 17/19] Fixed style --- .../MyThreadPool/MyThreadPool/MyThreadPool.csproj | 7 ------- .../MyThreadPoolTests/MyThreadPoolTests.csproj | 4 ---- 2 files changed, 11 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj index 226575e..eb2460e 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.csproj @@ -6,11 +6,4 @@ enable - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj index 24a0faa..faab430 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj +++ b/3Homework12.10.22/MyThreadPool/MyThreadPoolTests/MyThreadPoolTests.csproj @@ -14,10 +14,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - From f6b6880fdbae8c3803c169532df6dba7e18c8835 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Tue, 14 Feb 2023 14:47:11 +0300 Subject: [PATCH 18/19] Fixed threads waiting --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 1a70daf..4854c98 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -12,7 +12,7 @@ public class MyThreadPool private CancellationTokenSource source = new(); private bool isShutdown; private AutoResetEvent tasksOver; - private AutoResetEvent taskAdded; + private Semaphore taskCount = new Semaphore(0, 10000); /// /// Initializes a new instance of the class. @@ -29,11 +29,10 @@ public MyThreadPool(int threadCount = 10) this.tasks = new(); this.threads = new MyThread[threadCount]; this.tasksOver = new AutoResetEvent(false); - this.taskAdded = new AutoResetEvent(false); for (int i = 0; i < threadCount; ++i) { - this.threads[i] = new MyThread(this.tasks, this.source.Token, this.tasksOver, this.taskAdded); + this.threads[i] = new MyThread(this.tasks, this.source.Token, this.tasksOver, this.taskCount); } this.isShutdown = false; @@ -54,7 +53,8 @@ public IMyTask Submit(Func func) { var task = new MyTask(func, this); this.tasks.Add(() => task.Start()); - this.taskAdded.Set(); + this.tasksOver.Reset(); + this.taskCount.Release(); return task; } @@ -87,7 +87,7 @@ public void Shutdown() for (int i = 0; i < this.ThreadCount; i++) { - this.taskAdded.Set(); + this.taskCount.Release(); } var areJoined = true; @@ -113,13 +113,13 @@ private class MyThread private BlockingCollection collection; private int timeout = 5000; private AutoResetEvent tasksOver; - private AutoResetEvent taskAdded; + private Semaphore tasksCount; - public MyThread(BlockingCollection collection, CancellationToken token, AutoResetEvent tasksOver, AutoResetEvent taskAdded) + public MyThread(BlockingCollection collection, CancellationToken token, AutoResetEvent tasksOver, Semaphore tasksCount) { this.tasksOver = tasksOver; this.collection = collection; - this.taskAdded = taskAdded; + this.tasksCount = tasksCount; this.thread = new Thread(() => this.Start(token)); this.IsWorking = false; this.thread.Start(); @@ -148,7 +148,7 @@ private void Start(CancellationToken token) else { this.tasksOver.Set(); - this.taskAdded.WaitOne(); + this.tasksCount.WaitOne(); } } } From fcbb68097d54a97b9bedda2d747012eacd94ddf2 Mon Sep 17 00:00:00 2001 From: Niksen111 Date: Wed, 15 Feb 2023 10:19:54 +0300 Subject: [PATCH 19/19] Fixed continueWith --- .../MyThreadPool/MyThreadPool/MyThreadPool.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs index 4854c98..98c21be 100644 --- a/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs +++ b/3Homework12.10.22/MyThreadPool/MyThreadPool/MyThreadPool.cs @@ -161,6 +161,7 @@ private class MyTask : IMyTask private ManualResetEvent resetEvent = new(false); private T? result; private Exception? returnedException; + private BlockingCollection deferredTasks; /// /// Initializes a new instance of the class. @@ -172,6 +173,7 @@ public MyTask(Func func, MyThreadPool threadPool) this.func = func; this.pool = threadPool; this.IsCompleted = false; + this.deferredTasks = new BlockingCollection(); } /// @@ -207,21 +209,32 @@ public void Start() this.func = null; this.IsCompleted = true; this.resetEvent.Set(); + this.deferredTasks.CompleteAdding(); + foreach (var task in this.deferredTasks) + { + this.pool.Submit(() => task); + } } } /// public IMyTask ContinueWith(Func func1) { - TNewResult NewFunc() + if (this.result != null) + { + return this.pool.Submit(() => func1(this.Result)); + } + + MyTask newTask = new MyTask(() => func1(this.Result), this.pool); + try + { + this.deferredTasks.Add(() => newTask.Start()); + } + catch (InvalidOperationException) { - T realResult = this.Result; - return this.pool.Submit(() => func1(realResult)).Result; + return this.pool.Submit(() => func1(this.Result)); } - var newTask = new MyTask(NewFunc, this.pool); - var thread = new Thread(() => newTask.Start()); - thread.Start(); return newTask; } }