-
Notifications
You must be signed in to change notification settings - Fork 0
Добавила решение второй домашней работы #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net7.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
|
|
||
| <IsPackable>false</IsPackable> | ||
| <IsTestProject>true</IsTestProject> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> | ||
| <PackageReference Include="NUnit" Version="3.13.3" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.4.2" /> | ||
| <PackageReference Include="NUnit.Analyzers" Version="3.6.1" /> | ||
| <PackageReference Include="coverlet.collector" Version="3.2.0" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\Homework2\Homework2.csproj" /> | ||
| </ItemGroup> | ||
| </Project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| namespace Homework2.Tests; | ||
|
|
||
| public class Tests | ||
| { | ||
| private static IEnumerable<TestCaseData> LazyForResultTest => new TestCaseData[] | ||
| { | ||
| new TestCaseData(new LazySingleThread<int>(() => 2)), | ||
| new TestCaseData(new LazyMultyThread<int>(() => 2)), | ||
| }; | ||
|
|
||
| private static IEnumerable<TestCaseData> LazyForMultipleCallTest => new TestCaseData[] | ||
| { | ||
| new TestCaseData(new LazySingleThread<object>(() => new object())), | ||
| new TestCaseData(new LazyMultyThread<object>(() => new object())), | ||
| }; | ||
|
|
||
| private static IEnumerable<TestCaseData> LazyForExceptionTest => new TestCaseData[] | ||
| { | ||
| new TestCaseData(new LazySingleThread<object>(() => throw new Exception())), | ||
| new TestCaseData(new LazyMultyThread<object>(() => throw new Exception())), | ||
| }; | ||
|
|
||
| [TestCaseSource(nameof(LazyForResultTest))] | ||
| public void SingleLazyCallReturnResultTest(ILazy<int> lazy) | ||
| { | ||
| Assert.That(lazy.Get(), Is.EqualTo(2)); | ||
| } | ||
|
|
||
| [TestCaseSource(nameof(LazyForMultipleCallTest))] | ||
| public void MultipleLazyCallReturnsSameResultTest(ILazy<object> lazy) | ||
| { | ||
| object fstCallObject = lazy.Get()!; | ||
| object sndCallObject = lazy.Get()!; | ||
| Assert.That(fstCallObject, Is.EqualTo(sndCallObject)); | ||
| } | ||
|
|
||
| [TestCaseSource(nameof(LazyForExceptionTest))] | ||
| public void LazyThrowsExceptionTest(ILazy<object> lazy) | ||
| { | ||
| Assert.Throws<Exception>(() => lazy.Get()); | ||
| } | ||
|
|
||
| [Test] | ||
| public static void MultiThreadsReturnSameResultLazyTest() | ||
| { | ||
| var lazy = new LazyMultyThread<object>(() => new object()); | ||
| var threads = new Thread[20]; | ||
|
|
||
| var manualResetEvent = new ManualResetEvent(false); | ||
|
|
||
| var arrayOfResults = new object[20]; | ||
| for (int i = 0; i < 20; i++) | ||
| { | ||
| int localI = i; | ||
| threads[i] = new Thread(() => | ||
| { | ||
| manualResetEvent.WaitOne(); | ||
| arrayOfResults[localI] = lazy.Get()!; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Лучше "!" вообще никогда не пользоваться, потому что он убивает весь профит от nullability-анализа. Проверяйте явно на null лучше. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не поправлено. Можно, кстати, |
||
| }); | ||
| } | ||
|
|
||
| foreach (var thread in threads) | ||
| { | ||
| thread.Start(); | ||
| } | ||
|
|
||
| manualResetEvent.Set(); | ||
This comment was marked as resolved.
Sorry, something went wrong. |
||
|
|
||
| foreach (var thread in threads) | ||
| { | ||
| thread.Join(); | ||
| } | ||
|
|
||
| for (int i = 0; i < 19; i++) | ||
| { | ||
| Assert.That(arrayOfResults[i], Is.EqualTo(arrayOfResults[i + 1])); | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
Comment on lines
+79
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Лишние пустые строчки. Если они даже при беглом просмотре кода не бросаются Вам в глаза, Вам надо первый курс раззачесть :) |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| global using NUnit.Framework; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net7.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace Homework2; | ||
|
|
||
| /// <summary> | ||
| /// Interface for multy and single threads Lazy calculation. | ||
| /// </summary> | ||
| public interface ILazy<T> | ||
| { | ||
| T? Get(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Всё ещё надо комментарии |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| namespace Homework2; | ||
|
|
||
| /// <summary> | ||
| /// Lazy calculation class which works correctly with multithreading. | ||
| /// </summary> | ||
| public class LazyMultyThread<T> : ILazy<T> | ||
| { | ||
| private Func<T>? supplier; | ||
| private bool isFirstCall = true; | ||
| private Exception? supplierException = null; | ||
| private readonly object lockObject; | ||
| private T? result = default; | ||
|
|
||
| /// <summary> | ||
| /// Create new incstance of LazyMultThread class. | ||
| /// </summary> | ||
| /// <param name="calculation">Function that Lazy calculate</param> | ||
| public LazyMultyThread(Func<T> calculation) | ||
| { | ||
| supplier = calculation; | ||
| lockObject = new(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Method that returns calculated one time value. | ||
| /// </summary> | ||
| public T? Get() | ||
| { | ||
| if (Volatile.Read(ref isFirstCall)) | ||
| { | ||
| lock (lockObject) | ||
| { | ||
| if (Volatile.Read(ref isFirstCall)) | ||
| { | ||
| try | ||
| { | ||
| if (supplier == null) | ||
| { | ||
| throw new InvalidOperationException(); | ||
| } | ||
| result = supplier(); | ||
| return result; | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| supplierException = exception; | ||
| } | ||
| finally | ||
| { | ||
| supplier = null; | ||
| Volatile.Write(ref isFirstCall, false);//volatile write, result, supplier = null, supplierException in memory | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (Volatile.Read(ref supplierException) == null) //volatile read, values in memory are now in the cache of all threads | ||
| { | ||
| return result; | ||
| } | ||
| throw supplierException!; | ||
| } | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут тоже пустая строчка не нужна There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не поправлено |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| namespace Homework2; | ||
|
|
||
| /// <summary> | ||
| /// Lazy calculation class which works with singlethreading. | ||
| /// </summary> | ||
| public class LazySingleThread<T> : ILazy<T> | ||
| { | ||
| private Func<T>? supplier; | ||
| private bool isFirstCall = true; | ||
| private Exception? supplierException = null; | ||
| private T? result = default; | ||
|
|
||
| /// <summary> | ||
| /// Create new incstance of LazySingleThread class. | ||
| /// </summary> | ||
| /// <param name="calculation">Function that Lazy calculate</param> | ||
| public LazySingleThread(Func<T> calculation) | ||
| { | ||
| supplier = calculation; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Method that returns calculated one time value. | ||
| /// </summary> | ||
| public T? Get() | ||
| { | ||
| if (isFirstCall) | ||
| { | ||
| try | ||
| { | ||
| if (supplier == null) | ||
| { | ||
| throw new InvalidOperationException(); | ||
| } | ||
| result = supplier(); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| supplierException = exception; | ||
| } | ||
| finally | ||
| { | ||
| supplier = null; | ||
| isFirstCall = false; | ||
| } | ||
| } | ||
| if (supplierException == null) | ||
| { | ||
| return result; | ||
| } | ||
| throw supplierException; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.NET 7 умер
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Перейдите на .NET 8