From 4a929cdf7bd8baba4e176a54b357b54e850de948 Mon Sep 17 00:00:00 2001 From: Ksenia Nigmatulina Date: Fri, 22 Mar 2024 19:08:00 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=BE=D0=B9=20=D0=B4=D0=BE=D0=BC=D0=B0=D1=88?= =?UTF-8?q?=D0=BD=D0=B5=D0=B9=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Homework2.Tests/Homework2.Tests.csproj | 23 +++++++ Homework2.Tests/LazyTests.cs | 90 ++++++++++++++++++++++++++ Homework2.Tests/Usings.cs | 1 + Homework2/Homework2.csproj | 9 +++ Homework2/Homework2.sln | 31 +++++++++ Homework2/ILazy.cs | 1 + Homework2/LazyMultyThread.cs | 51 +++++++++++++++ Homework2/LazySingleThread.cs | 40 ++++++++++++ 8 files changed, 246 insertions(+) create mode 100644 Homework2.Tests/Homework2.Tests.csproj create mode 100644 Homework2.Tests/LazyTests.cs create mode 100644 Homework2.Tests/Usings.cs create mode 100644 Homework2/Homework2.csproj create mode 100644 Homework2/Homework2.sln create mode 100644 Homework2/ILazy.cs create mode 100644 Homework2/LazyMultyThread.cs create mode 100644 Homework2/LazySingleThread.cs diff --git a/Homework2.Tests/Homework2.Tests.csproj b/Homework2.Tests/Homework2.Tests.csproj new file mode 100644 index 0000000..0ba5997 --- /dev/null +++ b/Homework2.Tests/Homework2.Tests.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + + + + + + + diff --git a/Homework2.Tests/LazyTests.cs b/Homework2.Tests/LazyTests.cs new file mode 100644 index 0000000..7570005 --- /dev/null +++ b/Homework2.Tests/LazyTests.cs @@ -0,0 +1,90 @@ +namespace Homework2.Tests; + +using System; + +public class Tests +{ + private const int NumberOfMultyThreadTests = 100; + private const int NumberOfThreads = 10; + private static int NumberOfSingleThreadExperiments = 100; + static private ManualResetEvent? manualResetEvent; + + private static IEnumerable LazyImplementationExceptions => new TestCaseData[] + { + new TestCaseData(new LazyMultyThread(() => throw new Exception())), + new TestCaseData(new LazySingleThread(() => throw new Exception())) + }; + + private static IEnumerable LazyImplementationCheckOnceCreated => new TestCaseData[] + { + new TestCaseData(new LazyMultyThread(() => new Object())), + new TestCaseData(new LazySingleThread(() => new Object())) + }; + + [TestCaseSource(nameof(LazyImplementationExceptions))] + public void InvalidSupplierThrowsException(ILazy lazy) + { + Assert.Throws(() => lazy.Get()); + } + + [TestCaseSource(nameof(LazyImplementationCheckOnceCreated))] + public void FunctionCalledOnce(ILazy lazy) + { + var first = lazy.Get(); + var second = lazy.Get(); + Assert.That(first == second); + } + + [Test] + public void SingleThreadTest() + { + for (int i = 0; i < NumberOfSingleThreadExperiments; i++) + { + var lazy = new LazySingleThread(() => i * i); + Assert.That(lazy.Get() == i * i); + } + } + + [Test] + public void MultyThreadTest() + { + manualResetEvent = new ManualResetEvent(false); + var threads = new Thread[NumberOfThreads]; + + for (int i = 0; i < NumberOfMultyThreadTests; i++) + { + var localI = i; + var lazy = new LazyMultyThread(() => localI * localI); + manualResetEvent.Reset(); + + var results = new int[NumberOfThreads]; + for (int j = 0; j < NumberOfThreads; j++) + { + var localJ = j; + threads[j] = new Thread(() => + { + manualResetEvent.WaitOne(); + results[localJ] = lazy.Get(); + }); + } + + for (int j = 0; j < NumberOfThreads; j++) + { + threads[j].Start(); + } + + manualResetEvent.Set(); + + for (int j = 0; j < NumberOfThreads; j++) + { + threads[j].Join(); + } + + for (int j = 0; j < NumberOfThreads; j++) + { + Assert.That(results[j], Is.EqualTo(localI * localI)); + } + } + manualResetEvent.Reset(); + } +} \ No newline at end of file diff --git a/Homework2.Tests/Usings.cs b/Homework2.Tests/Usings.cs new file mode 100644 index 0000000..9a28bd8 --- /dev/null +++ b/Homework2.Tests/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; diff --git a/Homework2/Homework2.csproj b/Homework2/Homework2.csproj new file mode 100644 index 0000000..4658cbf --- /dev/null +++ b/Homework2/Homework2.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/Homework2/Homework2.sln b/Homework2/Homework2.sln new file mode 100644 index 0000000..ab274a3 --- /dev/null +++ b/Homework2/Homework2.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 25.0.1706.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Homework2", "Homework2.csproj", "{62DE394A-FA36-4AAE-92D4-E758A1023000}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Homework2.Tests", "..\Homework2.Tests\Homework2.Tests.csproj", "{9D5DF180-207E-4939-BC5E-873DA34309DA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {62DE394A-FA36-4AAE-92D4-E758A1023000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62DE394A-FA36-4AAE-92D4-E758A1023000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62DE394A-FA36-4AAE-92D4-E758A1023000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62DE394A-FA36-4AAE-92D4-E758A1023000}.Release|Any CPU.Build.0 = Release|Any CPU + {9D5DF180-207E-4939-BC5E-873DA34309DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D5DF180-207E-4939-BC5E-873DA34309DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D5DF180-207E-4939-BC5E-873DA34309DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D5DF180-207E-4939-BC5E-873DA34309DA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2604FC35-D54E-4E08-88FE-BC3F2DAE3C53} + EndGlobalSection +EndGlobal diff --git a/Homework2/ILazy.cs b/Homework2/ILazy.cs new file mode 100644 index 0000000..346a506 --- /dev/null +++ b/Homework2/ILazy.cs @@ -0,0 +1 @@ +public interface ILazy { T? Get(); } \ No newline at end of file diff --git a/Homework2/LazyMultyThread.cs b/Homework2/LazyMultyThread.cs new file mode 100644 index 0000000..85b80e6 --- /dev/null +++ b/Homework2/LazyMultyThread.cs @@ -0,0 +1,51 @@ + +namespace Homework2 +{ + public class LazyMultyThread : ILazy + { + private object lockObject; + private volatile bool isFirstCalculation = true; + private volatile Exception? exception; + private Func? supplier; + private T? result; + + public LazyMultyThread(Func function) + { + lockObject = new(); + supplier = function; + } + + public T? Get() + { + if (isFirstCalculation) + { + lock (lockObject) + { + if (isFirstCalculation) + { + try + { + result = supplier!(); + } + catch (Exception e) + { + exception = e; + } + finally + { + supplier = null; + isFirstCalculation = false; + } + } + } + } + if (exception == null) + { + return result; + } + + throw exception; + } + } +} + diff --git a/Homework2/LazySingleThread.cs b/Homework2/LazySingleThread.cs new file mode 100644 index 0000000..519e648 --- /dev/null +++ b/Homework2/LazySingleThread.cs @@ -0,0 +1,40 @@ + +namespace Homework2 +{ + public class LazySingleThread : ILazy + { + + private bool isFirstCalculation = true; + private T? result; + private Exception? exception; + private Func? supplier; + + public LazySingleThread(Func function) => supplier = function; + + public T? Get() + { + if (isFirstCalculation) + { + isFirstCalculation = false; + try + { + result = supplier!(); + } + catch (Exception e) + { + exception = e; + } + finally + { + supplier = null; + } + } + if (exception == null) + { + return result; + } + throw exception; + } + } +} + From bd88e37bc921ce2d4fa21974c4a14b86eee066f2 Mon Sep 17 00:00:00 2001 From: Ksenia Nigmatulina Date: Tue, 2 Apr 2024 13:50:57 +0300 Subject: [PATCH 2/4] =?UTF-8?q?C=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=D0=B0=20?= =?UTF-8?q?=D0=B2=D1=81=D0=B5=20=D0=B7=D0=B0=D0=BD=D0=BE=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Homework2.Tests/LazyTests.cs | 107 ++++++++++++++++------------------ Homework2/LazyMultyThread.cs | 75 ++++++++++++------------ Homework2/LazySingleThread.cs | 58 +++++++++--------- 3 files changed, 115 insertions(+), 125 deletions(-) diff --git a/Homework2.Tests/LazyTests.cs b/Homework2.Tests/LazyTests.cs index 7570005..30e87d6 100644 --- a/Homework2.Tests/LazyTests.cs +++ b/Homework2.Tests/LazyTests.cs @@ -1,90 +1,81 @@ -namespace Homework2.Tests; +using System.Numerics; -using System; +namespace Homework2.Tests; public class Tests { - private const int NumberOfMultyThreadTests = 100; - private const int NumberOfThreads = 10; - private static int NumberOfSingleThreadExperiments = 100; - static private ManualResetEvent? manualResetEvent; + private static IEnumerable LazyForResultTest => new TestCaseData[] + { + new TestCaseData(new LazySingleThread(() => 2)), + new TestCaseData(new LazyMultyThread(() => 2)), + }; - private static IEnumerable LazyImplementationExceptions => new TestCaseData[] + private static IEnumerable LazyForMultipleCallTest => new TestCaseData[] { - new TestCaseData(new LazyMultyThread(() => throw new Exception())), - new TestCaseData(new LazySingleThread(() => throw new Exception())) + new TestCaseData(new LazySingleThread(() => new object())), + new TestCaseData(new LazyMultyThread(() => new object())), }; - private static IEnumerable LazyImplementationCheckOnceCreated => new TestCaseData[] + private static IEnumerable LazyForExceptionTest => new TestCaseData[] { - new TestCaseData(new LazyMultyThread(() => new Object())), - new TestCaseData(new LazySingleThread(() => new Object())) + new TestCaseData(new LazySingleThread(() => throw new Exception())), + new TestCaseData(new LazyMultyThread(() => throw new Exception())), }; - [TestCaseSource(nameof(LazyImplementationExceptions))] - public void InvalidSupplierThrowsException(ILazy lazy) + [TestCaseSource(nameof(LazyForResultTest))] + public void SingleLazyCallReturnResultTest(ILazy lazy) { - Assert.Throws(() => lazy.Get()); + Assert.That(lazy.Get(), Is.EqualTo(2)); } - [TestCaseSource(nameof(LazyImplementationCheckOnceCreated))] - public void FunctionCalledOnce(ILazy lazy) + [TestCaseSource(nameof(LazyForMultipleCallTest))] + public void MultipleLazyCallReturnsSameResultTest(ILazy lazy) { - var first = lazy.Get(); - var second = lazy.Get(); - Assert.That(first == second); + object fstCallObject = lazy.Get()!; + object sndCallObject = lazy.Get()!; + Assert.That(fstCallObject, Is.EqualTo(sndCallObject)); } - [Test] - public void SingleThreadTest() + [TestCaseSource(nameof(LazyForExceptionTest))] + public void LazyThrowsExceptionTest(ILazy lazy) { - for (int i = 0; i < NumberOfSingleThreadExperiments; i++) - { - var lazy = new LazySingleThread(() => i * i); - Assert.That(lazy.Get() == i * i); - } + Assert.Throws(() => lazy.Get()); } [Test] - public void MultyThreadTest() + public static void MultiThreadsReturnSameResultLazyTest() { - manualResetEvent = new ManualResetEvent(false); - var threads = new Thread[NumberOfThreads]; + var lazy = new LazyMultyThread(() => new object()); + var threads = new Thread[20]; - for (int i = 0; i < NumberOfMultyThreadTests; i++) - { - var localI = i; - var lazy = new LazyMultyThread(() => localI * localI); - manualResetEvent.Reset(); + var manualResetEvent = new ManualResetEvent(false); - var results = new int[NumberOfThreads]; - for (int j = 0; j < NumberOfThreads; j++) + var listOfResults = new List(); + for (int i = 0; i < 20; i++) + { + int localI = i; + threads[i] = new Thread(() => { - var localJ = j; - threads[j] = new Thread(() => - { - manualResetEvent.WaitOne(); - results[localJ] = lazy.Get(); - }); - } + listOfResults.Add(lazy.Get()!); + }); + } - for (int j = 0; j < NumberOfThreads; j++) - { - threads[j].Start(); - } + foreach (var thread in threads) + { + thread.Start(); + } - manualResetEvent.Set(); + manualResetEvent.Set(); - for (int j = 0; j < NumberOfThreads; j++) - { - threads[j].Join(); - } + foreach (var thread in threads) + { + thread.Join(); + } - for (int j = 0; j < NumberOfThreads; j++) - { - Assert.That(results[j], Is.EqualTo(localI * localI)); - } + for (int i = 0; i < 19; i++) + { + Assert.That(listOfResults[i], Is.EqualTo(listOfResults[i + 1])); } - manualResetEvent.Reset(); } + } \ No newline at end of file diff --git a/Homework2/LazyMultyThread.cs b/Homework2/LazyMultyThread.cs index 85b80e6..4087786 100644 --- a/Homework2/LazyMultyThread.cs +++ b/Homework2/LazyMultyThread.cs @@ -1,51 +1,50 @@ - -namespace Homework2 +namespace Homework2; + +public class LazyMultyThread : ILazy { - public class LazyMultyThread : ILazy - { - private object lockObject; - private volatile bool isFirstCalculation = true; - private volatile Exception? exception; - private Func? supplier; - private T? result; + private Func? supplier; + private bool isFirstCall = true; + private Exception? supplierException = null; + private readonly object lockObject; + private T? result = default; - public LazyMultyThread(Func function) - { - lockObject = new(); - supplier = function; - } + public LazyMultyThread(Func calculation) + { + supplier = calculation; + lockObject = new(); + } - public T? Get() + public T? Get() + { + if (Volatile.Read(ref isFirstCall)) { - if (isFirstCalculation) + lock (lockObject) { - lock (lockObject) + if (Volatile.Read(ref isFirstCall)) { - if (isFirstCalculation) + try + { + result = supplier!(); + return result; + } + catch (Exception exception) + { + supplierException = exception; + } + finally { - try - { - result = supplier!(); - } - catch (Exception e) - { - exception = e; - } - finally - { - supplier = null; - isFirstCalculation = false; - } + supplier = null; + isFirstCall = false; + Volatile.Write(ref isFirstCall, false);//volatile write, result, supplier = null, supplierException in memory } } } - if (exception == null) - { - return result; - } - - throw exception; } + if (Volatile.Read(ref supplierException) == null) //volatile read, values ​​in memory are now in the cache of all threads + { + return result; + } + throw supplierException!; } -} +} \ No newline at end of file diff --git a/Homework2/LazySingleThread.cs b/Homework2/LazySingleThread.cs index 519e648..1a365a5 100644 --- a/Homework2/LazySingleThread.cs +++ b/Homework2/LazySingleThread.cs @@ -1,40 +1,40 @@ - -namespace Homework2 -{ - public class LazySingleThread : ILazy - { +namespace Homework2; - private bool isFirstCalculation = true; - private T? result; - private Exception? exception; - private Func? supplier; +public class LazySingleThread : ILazy +{ + private Func? supplier; + private bool isFirstCall = true; + private Exception? supplierException = null; + private T? result = default; - public LazySingleThread(Func function) => supplier = function; + public LazySingleThread(Func calculation) + { + supplier = calculation; + } - public T? Get() + public T? Get() + { + if (isFirstCall) { - if (isFirstCalculation) + try + { + result = supplier!(); + } + catch (Exception exception) { - isFirstCalculation = false; - try - { - result = supplier!(); - } - catch (Exception e) - { - exception = e; - } - finally - { - supplier = null; - } + supplierException = exception; } - if (exception == null) + finally { - return result; + supplier = null; + isFirstCall = false; } - throw exception; } + if (supplierException == null) + { + return result; + } + throw supplierException; } -} +} \ No newline at end of file From 735373c921d73183b0c5bc26ce93ffe82f93ba62 Mon Sep 17 00:00:00 2001 From: Ksenia Nigmatulina Date: Tue, 2 Apr 2024 13:58:58 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2,=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=20=D0=B8=D0=B7=D0=B1=D0=B5=D0=B6=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=20=D1=81=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=B2=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D0=BA=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Homework2.Tests/LazyTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Homework2.Tests/LazyTests.cs b/Homework2.Tests/LazyTests.cs index 30e87d6..cd7ff17 100644 --- a/Homework2.Tests/LazyTests.cs +++ b/Homework2.Tests/LazyTests.cs @@ -1,5 +1,4 @@ -using System.Numerics; - + namespace Homework2.Tests; public class Tests @@ -50,13 +49,13 @@ public static void MultiThreadsReturnSameResultLazyTest() var manualResetEvent = new ManualResetEvent(false); - var listOfResults = new List(); + var arrayOfResults = new object[20]; for (int i = 0; i < 20; i++) { int localI = i; threads[i] = new Thread(() => { - listOfResults.Add(lazy.Get()!); + arrayOfResults[localI] = lazy.Get()!; }); } @@ -74,8 +73,9 @@ public static void MultiThreadsReturnSameResultLazyTest() for (int i = 0; i < 19; i++) { - Assert.That(listOfResults[i], Is.EqualTo(listOfResults[i + 1])); + Assert.That(arrayOfResults[i], Is.EqualTo(arrayOfResults[i + 1])); } } + } \ No newline at end of file From 0ca0154096d51f162d2884777bc1fd3e99e8a7ea Mon Sep 17 00:00:00 2001 From: Ksenia Nigmatulina Date: Wed, 10 Apr 2024 12:58:55 +0400 Subject: [PATCH 4/4] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Homework2.Tests/LazyTests.cs | 4 ++-- Homework2/ILazy.cs | 10 +++++++++- Homework2/LazyMultyThread.cs | 17 +++++++++++++++-- Homework2/LazySingleThread.cs | 17 +++++++++++++++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Homework2.Tests/LazyTests.cs b/Homework2.Tests/LazyTests.cs index cd7ff17..3e50bc2 100644 --- a/Homework2.Tests/LazyTests.cs +++ b/Homework2.Tests/LazyTests.cs @@ -1,5 +1,4 @@ - -namespace Homework2.Tests; +namespace Homework2.Tests; public class Tests { @@ -55,6 +54,7 @@ public static void MultiThreadsReturnSameResultLazyTest() int localI = i; threads[i] = new Thread(() => { + manualResetEvent.WaitOne(); arrayOfResults[localI] = lazy.Get()!; }); } diff --git a/Homework2/ILazy.cs b/Homework2/ILazy.cs index 346a506..1a54c4f 100644 --- a/Homework2/ILazy.cs +++ b/Homework2/ILazy.cs @@ -1 +1,9 @@ -public interface ILazy { T? Get(); } \ No newline at end of file +namespace Homework2; + +/// +/// Interface for multy and single threads Lazy calculation. +/// +public interface ILazy +{ + T? Get(); +} \ No newline at end of file diff --git a/Homework2/LazyMultyThread.cs b/Homework2/LazyMultyThread.cs index 4087786..4befad3 100644 --- a/Homework2/LazyMultyThread.cs +++ b/Homework2/LazyMultyThread.cs @@ -1,5 +1,8 @@ namespace Homework2; +/// +/// Lazy calculation class which works correctly with multithreading. +/// public class LazyMultyThread : ILazy { private Func? supplier; @@ -8,12 +11,19 @@ public class LazyMultyThread : ILazy private readonly object lockObject; private T? result = default; + /// + /// Create new incstance of LazyMultThread class. + /// + /// Function that Lazy calculate public LazyMultyThread(Func calculation) { supplier = calculation; lockObject = new(); } + /// + /// Method that returns calculated one time value. + /// public T? Get() { if (Volatile.Read(ref isFirstCall)) @@ -24,7 +34,11 @@ public LazyMultyThread(Func calculation) { try { - result = supplier!(); + if (supplier == null) + { + throw new InvalidOperationException(); + } + result = supplier(); return result; } catch (Exception exception) @@ -34,7 +48,6 @@ public LazyMultyThread(Func calculation) finally { supplier = null; - isFirstCall = false; Volatile.Write(ref isFirstCall, false);//volatile write, result, supplier = null, supplierException in memory } } diff --git a/Homework2/LazySingleThread.cs b/Homework2/LazySingleThread.cs index 1a365a5..336a571 100644 --- a/Homework2/LazySingleThread.cs +++ b/Homework2/LazySingleThread.cs @@ -1,5 +1,8 @@ namespace Homework2; +/// +/// Lazy calculation class which works with singlethreading. +/// public class LazySingleThread : ILazy { private Func? supplier; @@ -7,18 +10,29 @@ public class LazySingleThread : ILazy private Exception? supplierException = null; private T? result = default; + /// + /// Create new incstance of LazySingleThread class. + /// + /// Function that Lazy calculate public LazySingleThread(Func calculation) { supplier = calculation; } + /// + /// Method that returns calculated one time value. + /// public T? Get() { if (isFirstCall) { try { - result = supplier!(); + if (supplier == null) + { + throw new InvalidOperationException(); + } + result = supplier(); } catch (Exception exception) { @@ -36,5 +50,4 @@ public LazySingleThread(Func calculation) } throw supplierException; } - } \ No newline at end of file