1 Commits

Author SHA1 Message Date
e6e89afa88 commit1 2023-12-18 16:06:00 +04:00
41 changed files with 582 additions and 745 deletions

View File

@@ -0,0 +1,86 @@
# Отчет по лабораторной работе №3
Выполнил студент гр. ИСЭбд-41 Мельников К.Ю.
## REST API, Gateway и синхронный обмен между микросервисами
## Создание микросервисов
1. С помощью команды `dotnet new web -n worker-1` в терминале создал первый микросервис
2. Добавил решение командой `dotnet new sln`
3. Связал решение и проект командой `dotnet sln worker-1.sln add worker-1.csproj`
4. Повторил действие для второго микросервиса
5. Добавил библиотеку Swagger и OpenAi в проекты и запустил с помощью команды `dotnet run`
Скриншоты протестированных микросервисов:
![](scrins/1.png)
## Реализация синхронного обмена
Реализовал код, который вызывает сихронно данные из соседнего микросервиса.
```cs
//worker-2
app.MapGet("/Parts/", async () =>
{
var httpClient = new HttpClient();
var secondWorkerResponse = await httpClient.GetStringAsync("http://worker-1:8080/");
return secondWorkerResponse.ToArray();
})
.WithName("GetCars")
.WithOpenApi();
```
## Реализация gateway при помощи nginx
Добавил nginx.conf:
```conf
server {
listen 8080;
listen [::]:8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-1;
}
location /worker-2/ {
proxy_pass http://worker-2:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-2;
}
}
```
Результат, после выполнения команды `docker-compose up`:
Docker:
![](scrins/2.png)
index.html на gateway-1:
![](scrins/3.png)
worker-1:
![](scrins/5.png)
worker-2:
![](scrins/4.png)

View File

@@ -0,0 +1,15 @@
version: "3.1"
services:
worker-1:
build: ./worker-1
worker-2:
build: ./worker-2
depends_on:
- worker-1
gateway:
image: nginx:latest
ports:
- 8080:8080
volumes:
- ./static:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

View File

@@ -0,0 +1,26 @@
server {
listen 8080;
listen [::]:8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-1;
}
location /worker-2/ {
proxy_pass http://worker-2:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-2;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Тестовое приложение для л/р 3</title>
</head>
<body>
<p>Мельников К.Ю. ИСЭбд-41.</p>
<p><a href="/worker-1/">Отправить запрос к worker-1</a></p>
<p><a href="/worker-2/">Отправить запрос к worker-2</a></p>
</body>
</html>

View File

@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-1.dll"]

View File

@@ -0,0 +1,111 @@
List<Cars> cars = new()
{
new Cars() { Uuid= Guid.Parse("6a1b4a72-5669-41fe-8d5b-106dc86f58bd"), Model = "Priora", Brand = "Lada"},
new Cars() { Uuid= Guid.Parse("464bbdb8-39c0-4644-b9c0-3df1c484ea7e"), Model = "CRV", Brand = "Honda"},
new Cars() { Uuid= Guid.Parse("f8692bea-b7e6-4164-b564-a921f16c35c9"), Model = "Jumper", Brand = "Citroen"},
};
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/", () =>
{
return cars.Select(r => new CarEntityDto()
{
Uuid = r.Uuid,
Model = r.Model,
Brand = r.Brand,
});
})
.WithName("GetCars")
.WithOpenApi();
app.MapGet("/{uuid}", (Guid uuid) =>
{
var car = cars.FirstOrDefault(r => r.Uuid == uuid);
if (car == null)
return Results.NotFound();
return Results.Json(new CarEntityDto()
{
Uuid = car.Uuid,
Model = car.Model,
Brand = car.Brand,
});
})
.WithName("GetCarByGUID")
.WithOpenApi();
app.MapPost("/{model}/{brand}", (string Model, string Brand) =>
{
Guid NewGuid = Guid.NewGuid();
cars.Add(new Cars() { Uuid = NewGuid, Model = (string)Model, Brand = (string)Brand});
var car = cars.FirstOrDefault(r => r.Uuid == NewGuid);
if (car == null)
return Results.NotFound();
return Results.Json(new CarEntityDto()
{
Uuid = car.Uuid,
Model = car.Model,
Brand = car.Brand,
});
})
.WithName("PostCar")
.WithOpenApi();
app.MapPatch("/{uuid}/{model}/{brand}", (Guid uuid, string ?model, string ?brand) =>
{
var car = cars.FirstOrDefault(r => r.Uuid == uuid);
if (car == null)
return Results.NotFound();
if (model != null) car.Model = model;
if (brand != null) car.Brand = brand;
return Results.Json(new CarEntityDto()
{
Uuid = car.Uuid,
Model = car.Model,
Brand = car.Brand,
});
})
.WithName("UpdateCar")
.WithOpenApi();
app.MapDelete("/{uuid}", (Guid uuid) =>
{
var car = cars.FirstOrDefault(r => r.Uuid == uuid);
if (car == null)
return Results.NotFound();
cars.Remove(car);
return Results.Json(new CarEntityDto()
{
Uuid = car.Uuid,
Model = car.Model,
Brand = car.Brand,
});
})
.WithName("DeleteCarByGUID")
.WithOpenApi();
app.Run();
public class Cars
{
public Guid Uuid { get; set; }
public string Model { get; set; } = string.Empty;
public string Brand { get; set; } = string.Empty;
}
public class CarEntityDto : Cars { }

View File

@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51956",
"sslPort": 44303
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5197",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7027;http://localhost:5197",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_1</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -1,25 +1,22 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.3.32811.315 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab6", "Lab6.csproj", "{5E467820-7298-4466-AD82-CEDEB780CA68}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "worker-1", "worker-1.csproj", "{90F6C7BD-78E2-47C8-A702-DD47E74D3865}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5E467820-7298-4466-AD82-CEDEB780CA68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E467820-7298-4466-AD82-CEDEB780CA68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E467820-7298-4466-AD82-CEDEB780CA68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E467820-7298-4466-AD82-CEDEB780CA68}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
SolutionGuid = {7933D480-E7B1-4658-8726-83CCD3BED00D} {90F6C7BD-78E2-47C8-A702-DD47E74D3865}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90F6C7BD-78E2-47C8-A702-DD47E74D3865}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90F6C7BD-78E2-47C8-A702-DD47E74D3865}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90F6C7BD-78E2-47C8-A702-DD47E74D3865}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-2.dll"]

View File

@@ -0,0 +1,139 @@
List<Parts> parts = new()
{
new Parts() { Uuid= Guid.NewGuid(), Name = "Engine", IsNew = true, IdCar = Guid.Parse("6a1b4a72-5669-41fe-8d5b-106dc86f58bd") },
new Parts() { Uuid= Guid.NewGuid(), Name = "Wheels", IsNew = false, IdCar = Guid.Parse("f8692bea-b7e6-4164-b564-a921f16c35c9") },
new Parts() { Uuid= Guid.NewGuid(), Name = "Transmission", IsNew = false, IdCar = Guid.Parse("464bbdb8-39c0-4644-b9c0-3df1c484ea7e") },
new Parts() { Uuid= Guid.NewGuid(), Name = "Radiator ", IsNew = true, IdCar = Guid.Parse("464bbdb8-39c0-4644-b9c0-3df1c484ea7e") },
};
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/", () =>
{
return parts.Select(r => new PartEntityDto()
{
Uuid = r.Uuid,
Name = r.Name,
IsNew = r.IsNew,
IdCar = r.IdCar,
});
})
.WithName("GetParts")
.WithOpenApi();
app.MapGet("/{uuid}", (Guid uuid) =>
{
var part = parts.FirstOrDefault(r => r.Uuid == uuid);
if (part == null)
return Results.NotFound();
return Results.Json(new PartEntityDto()
{
Uuid = part.Uuid,
Name = part.Name,
IsNew = part.IsNew,
IdCar = part.IdCar,
});
})
.WithName("GetPartByGUID")
.WithOpenApi();
app.MapPost("/{name}/{isNew}/{idCar}", (string? Name, bool IsNew, Guid IdCar) =>
{
Guid NewGuid = Guid.NewGuid();
parts.Add(new Parts() { Uuid = NewGuid, Name = (string)Name, IsNew = (bool)IsNew, IdCar = (Guid)IdCar });
var part = parts.FirstOrDefault(r => r.Uuid == NewGuid);
if (part == null)
return Results.NotFound();
return Results.Json(new PartEntityDto()
{
Uuid = part.Uuid,
Name = part.Name,
IsNew = part.IsNew,
IdCar = part.IdCar,
});
})
.WithName("PostPart")
.WithOpenApi();
app.MapPatch("/{uuid}/{name}/{isNew}/{idCar}", (Guid uuid, string ?name, bool isNew, Guid idCar) =>
{
var part = parts.FirstOrDefault(r => r.Uuid == uuid);
if (part == null)
return Results.NotFound();
if (name != ",") part.Name = name;
if (isNew != part.IsNew) part.IsNew = isNew;
if (idCar != part.IdCar) part.IdCar = idCar;
return Results.Json(new PartEntityDto()
{
Uuid = part.Uuid,
Name = part.Name,
IsNew = part.IsNew,
IdCar = part.IdCar,
});
})
.WithName("UpdatePart")
.WithOpenApi();
app.MapDelete("/{uuid}", (Guid uuid) =>
{
var part = parts.FirstOrDefault(r => r.Uuid == uuid);
if (part == null)
return Results.NotFound();
parts.Remove(part);
return Results.Json(new PartEntityDto()
{
Uuid = part.Uuid,
Name = part.Name,
IsNew = part.IsNew,
IdCar = part.IdCar,
});
})
.WithName("DeletePart")
.WithOpenApi();
app.MapGet("/Parts/", async () =>
{
var httpClient = new HttpClient();
var secondWorkerResponse = await httpClient.GetStringAsync("http://worker-1:8080/");
return secondWorkerResponse.ToArray();
})
.WithName("GetCars")
.WithOpenApi();
app.Run();
public class Parts
{
public Guid Uuid { get; set; }
public string Name { get; set; } = string.Empty;
public bool IsNew { get; set; }
public Guid IdCar { get; set; }
}
public class PartEntityDto : Parts { }
public class Cars
{
public Guid Uuid { get; set; }
public string Model { get; set; } = string.Empty;
public string Brand { get; set; } = string.Empty;
}
public class CarEntityDto : Cars { }

View File

@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:36404",
"sslPort": 44384
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5101",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7125;http://localhost:5101",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_2</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "worker-2", "worker-2.csproj", "{C9D63524-2C63-4E86-91B6-D86955CFA5F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C9D63524-2C63-4E86-91B6-D86955CFA5F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9D63524-2C63-4E86-91B6-D86955CFA5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9D63524-2C63-4E86-91B6-D86955CFA5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9D63524-2C63-4E86-91B6-D86955CFA5F8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -1,46 +0,0 @@
namespace Lab6
{
public class Alg1
{
public int Begin(int[,] matrix)
{
return CalculateDeterminant(matrix);
}
static int CalculateDeterminant(int[,] matrix)
{
int n = matrix.GetLength(0);
if (n == 1)
{
return matrix[0, 0];
}
int determinant = 0;
for (int j = 0; j < n; j++)
{
int[,] submatrix = new int[n - 1, n - 1];
for (int i = 1; i < n; i++)
{
for (int k = 0; k < n; k++)
{
if (k < j)
{
submatrix[i - 1, k] = matrix[i, k];
}
else if (k > j)
{
submatrix[i - 1, k - 1] = matrix[i, k];
}
}
}
determinant += (int)Math.Pow(-1, j) * matrix[0, j] * CalculateDeterminant(submatrix);
}
return determinant;
}
}
}

View File

@@ -1,90 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Drawing.Drawing2D;
namespace Lab6
{
public class Alg2
{
public double Begin(double[,] matrixA, int threadCount)
{
int size = matrixA.GetLength(0);
if (size == 1)
{
return matrixA[0, 0];
}
else if (size == 2)
{
return matrixA[0, 0] * matrixA[1, 1] - matrixA[0, 1] * matrixA[1, 0];
}
else
{
double determinant = 0;
object lockObject = new object();
Parallel.For(0, size, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, i =>
{
double[,] subMatrix = GetSubMatrix(matrixA, i);
double subDeterminant = matrixA[0, i] * Determinant(subMatrix);
lock (lockObject)
{
determinant += Math.Pow(-1, i) * subDeterminant;
}
});
return determinant;
}
}
static double[,] GetSubMatrix(double[,] matrix, int columnIndex)
{
int size = matrix.GetLength(0);
double[,] subMatrix = new double[size - 1, size - 1];
for (int i = 1; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (j < columnIndex)
{
subMatrix[i - 1, j] = matrix[i, j];
}
else if (j > columnIndex)
{
subMatrix[i - 1, j - 1] = matrix[i, j];
}
}
}
return subMatrix;
}
static double Determinant(double[,] matrix)
{
int size = matrix.GetLength(0);
if (size == 1)
{
return matrix[0, 0];
}
else if (size == 2)
{
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
}
else
{
double determinant = 0;
for (int i = 0; i < size; i++)
{
double[,] subMatrix = GetSubMatrix(matrix, i);
determinant += Math.Pow(-1, i) * matrix[0, i] * Determinant(subMatrix);
}
return determinant;
}
}
}
}

View File

@@ -1,95 +0,0 @@
using System.Drawing;
namespace Lab6
{
public class Controller
{
public double[,] ConvertArray(int[,] intArray)
{
int rows = intArray.GetLength(0);
int cols = intArray.GetLength(1);
double[,] doubleArray = new double[rows, cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
doubleArray[i, j] = (double)intArray[i, j];
}
}
return doubleArray;
}
public string PrintResultMatrix(int[,] result)
{
string resultString = "";
for (int i = 0; i < result.GetLength(0); i++)
{
for (int j = 0; j < result.GetLength(1); j++)
{
resultString += result[i, j];
if (j != result.GetLength(1) - 1)
{
resultString += " ";
}
}
resultString += Environment.NewLine;
}
return resultString;
}
public int[,] GetMatrixFromTextbox(string inputText)
{
string[] lines = inputText.Split(Environment.NewLine);
int numRows = lines.Length;
int numCol = lines[0].Split(' ').Length;
int[,] matrix = new int[numRows, numCol];
for (int i = 0; i < numRows; i++)
{
string[] elements = lines[i].Split(' ');
for (int j = 0; j < numCol; j++)
{
matrix[i, j] = int.Parse(elements[j]);
}
}
return matrix;
}
public string GetTextFromFile(string filePath)
{
string text = "";
using (StreamReader sr = new StreamReader(filePath))
{
text = sr.ReadToEnd();
}
return text;
}
public int[,] GenerateNewMatrix(int count)
{
Random random = new Random();
int[,] matrix = new int[count, count];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
matrix[i, j] = random.Next(1, 5);
}
}
return matrix;
}
}
}

View File

@@ -1,229 +0,0 @@
namespace Lab6
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
textBoxMatrix1 = new TextBox();
textBoxResult = new TextBox();
buttonAlg1 = new Button();
buttonAlg2 = new Button();
openFileDialog1 = new OpenFileDialog();
label3 = new Label();
labelResultTime = new Label();
label4 = new Label();
countStream = new NumericUpDown();
buttonGenerateMatrix1 = new Button();
label5 = new Label();
genCountRowCol = new NumericUpDown();
button1 = new Button();
label1 = new Label();
((System.ComponentModel.ISupportInitialize)countStream).BeginInit();
((System.ComponentModel.ISupportInitialize)genCountRowCol).BeginInit();
SuspendLayout();
//
// textBoxMatrix1
//
textBoxMatrix1.Location = new Point(12, 50);
textBoxMatrix1.Multiline = true;
textBoxMatrix1.Name = "textBoxMatrix1";
textBoxMatrix1.Size = new Size(258, 258);
textBoxMatrix1.TabIndex = 0;
//
// textBoxResult
//
textBoxResult.Location = new Point(446, 211);
textBoxResult.Multiline = true;
textBoxResult.Name = "textBoxResult";
textBoxResult.Size = new Size(258, 40);
textBoxResult.TabIndex = 1;
//
// buttonAlg1
//
buttonAlg1.BackColor = Color.PaleGreen;
buttonAlg1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonAlg1.Location = new Point(12, 314);
buttonAlg1.Name = "buttonAlg1";
buttonAlg1.Size = new Size(258, 40);
buttonAlg1.TabIndex = 2;
buttonAlg1.Text = "Обычный алгоритм";
buttonAlg1.UseVisualStyleBackColor = false;
buttonAlg1.Click += buttonAlg1_Click;
//
// buttonAlg2
//
buttonAlg2.BackColor = Color.PaleGreen;
buttonAlg2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
buttonAlg2.Location = new Point(12, 360);
buttonAlg2.Name = "buttonAlg2";
buttonAlg2.Size = new Size(258, 39);
buttonAlg2.TabIndex = 8;
buttonAlg2.Text = "Паралелльный алгоритм";
buttonAlg2.UseVisualStyleBackColor = false;
buttonAlg2.Click += buttonAlg2_Click;
//
// openFileDialog1
//
openFileDialog1.FileName = "openFileDialog1";
//
// label3
//
label3.AutoSize = true;
label3.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point);
label3.Location = new Point(293, 277);
label3.Name = "label3";
label3.Size = new Size(111, 30);
label3.TabIndex = 9;
label3.Text = "Результат:";
//
// labelResultTime
//
labelResultTime.AutoSize = true;
labelResultTime.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point);
labelResultTime.Location = new Point(395, 277);
labelResultTime.Name = "labelResultTime";
labelResultTime.Size = new Size(0, 30);
labelResultTime.TabIndex = 10;
//
// label4
//
label4.AutoSize = true;
label4.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point);
label4.Location = new Point(293, 62);
label4.Name = "label4";
label4.Size = new Size(214, 30);
label4.TabIndex = 12;
label4.Text = "Количество потоков:";
//
// countStream
//
countStream.Location = new Point(610, 69);
countStream.Maximum = new decimal(new int[] { 10, 0, 0, 0 });
countStream.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
countStream.Name = "countStream";
countStream.Size = new Size(66, 23);
countStream.TabIndex = 13;
countStream.Value = new decimal(new int[] { 4, 0, 0, 0 });
//
// buttonGenerateMatrix1
//
buttonGenerateMatrix1.BackColor = Color.PaleGreen;
buttonGenerateMatrix1.Location = new Point(12, 12);
buttonGenerateMatrix1.Name = "buttonGenerateMatrix1";
buttonGenerateMatrix1.Size = new Size(258, 32);
buttonGenerateMatrix1.TabIndex = 14;
buttonGenerateMatrix1.Text = "Сгенерировать";
buttonGenerateMatrix1.UseVisualStyleBackColor = false;
buttonGenerateMatrix1.Click += buttonGenerateMatrix1_Click;
//
// label5
//
label5.AutoSize = true;
label5.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point);
label5.Location = new Point(293, 14);
label5.Name = "label5";
label5.Size = new Size(292, 30);
label5.TabIndex = 16;
label5.Text = "Размерность при генерации:";
//
// genCountRowCol
//
genCountRowCol.Location = new Point(610, 21);
genCountRowCol.Maximum = new decimal(new int[] { 500, 0, 0, 0 });
genCountRowCol.Minimum = new decimal(new int[] { 2, 0, 0, 0 });
genCountRowCol.Name = "genCountRowCol";
genCountRowCol.Size = new Size(66, 23);
genCountRowCol.TabIndex = 17;
genCountRowCol.Value = new decimal(new int[] { 3, 0, 0, 0 });
//
// button1
//
button1.BackColor = Color.RosyBrown;
button1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
button1.Location = new Point(12, 423);
button1.Name = "button1";
button1.Size = new Size(258, 46);
button1.TabIndex = 22;
button1.Text = "Очистить матрицы";
button1.UseVisualStyleBackColor = false;
button1.Click += button1_Click;
//
// label1
//
label1.AutoSize = true;
label1.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point);
label1.Location = new Point(293, 211);
label1.Name = "label1";
label1.Size = new Size(147, 30);
label1.TabIndex = 23;
label1.Text = "Детерминант:";
//
// Form1
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.PapayaWhip;
ClientSize = new Size(729, 491);
Controls.Add(label1);
Controls.Add(button1);
Controls.Add(genCountRowCol);
Controls.Add(label5);
Controls.Add(buttonGenerateMatrix1);
Controls.Add(countStream);
Controls.Add(label4);
Controls.Add(labelResultTime);
Controls.Add(label3);
Controls.Add(buttonAlg2);
Controls.Add(buttonAlg1);
Controls.Add(textBoxResult);
Controls.Add(textBoxMatrix1);
Name = "Form1";
Text = "Умножение матриц: Мельников К.Ю. ИСЭбд-41";
((System.ComponentModel.ISupportInitialize)countStream).EndInit();
((System.ComponentModel.ISupportInitialize)genCountRowCol).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxMatrix1;
private TextBox textBoxResult;
private Button buttonAlg1;
private Button buttonAlg2;
private OpenFileDialog openFileDialog1;
private Label label3;
private Label labelResultTime;
private Label label4;
private NumericUpDown countStream;
private Button buttonGenerateMatrix1;
private Label label5;
private NumericUpDown genCountRowCol;
private Button button1;
private Label label1;
}
}

View File

@@ -1,84 +0,0 @@
using System.Diagnostics;
namespace Lab6
{
public partial class Form1 : Form
{
public Controller service;
public Alg1 Alg1;
public Alg2 Alg2;
public Stopwatch stopwatch;
public int[,] matrixA;
public Form1()
{
InitializeComponent();
this.service = new Controller();
this.Alg1 = new Alg1();
this.Alg2 = new Alg2();
this.stopwatch = new Stopwatch();
}
private void buttonAlg1_Click(object sender, EventArgs e)
{
try
{
stopwatch.Start();
int result = Alg1.Begin(matrixA);
stopwatch.Stop();
labelResultTime.Text = "" + stopwatch.Elapsed;
textBoxResult.Text = Convert.ToString(result);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
stopwatch.Reset();
}
private void buttonAlg2_Click(object sender, EventArgs e)
{
try
{
double[,] doubleMatrix = service.ConvertArray(matrixA);
stopwatch.Start();
textBoxResult.Text = Convert.ToString(Alg2.Begin(doubleMatrix, (int)countStream.Value));
stopwatch.Stop();
labelResultTime.Text = "" + stopwatch.Elapsed;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
stopwatch.Reset();
}
private void buttonLoadMatrix1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
string filePath = openFileDialog1.FileName;
string result = service.GetTextFromFile(filePath);
textBoxMatrix1.Text = result;
matrixA = service.GetMatrixFromTextbox(result);
}
private void buttonGenerateMatrix1_Click(object sender, EventArgs e)
{
matrixA = service.GenerateNewMatrix((int)genCountRowCol.Value);
textBoxMatrix1.Text = service.PrintResultMatrix(matrixA);
}
private void button1_Click(object sender, EventArgs e)
{
textBoxMatrix1.Text = "";
textBoxResult.Text = "";
matrixA = null;
}
}
}

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>7, 19</value>
</metadata>
</root>

View File

@@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -1,17 +0,0 @@
namespace Lab6
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
}

View File

@@ -1,39 +0,0 @@
# Отчет по лабораторной работе №6
Выполнил студент гр. ИСЭбд-41 Мельников К.Ю.
## Создание приложения
Выбрал язык C#, Windows Forms.
Приложение имеет поле ввода матрицы, в которое можно через пробел вносить элементы матрицы. Можно сгенерировать матрицу указав её размерность. При необходимости можно очистить матрицу и определитель. Количество потоков в параллельном алгоритме регулируется в соответствующем поле.
Попробуем запустить обычный и паралелльный алгоритмы на матрицах 2х2 и зафиксировать результат выполнения по времени.
![](scrins/1.png)
![](scrins/1.1.png)
## Бенчмарки
Протестируем обычный и параллельный алгоритм определение детерминанта на различной размерности матрицы.
В ходе экспериментов было установлено, что обработка матрицы размеров больше 11х11 занимает слишком много времени в обычном и параллельном алгоритмах, поэтому для тестирования возьмем матрицы 7х7, 9х9 и 11х11.
Сверху отображен результат обычного алгоритма, снизу паралелльного.
Матрица 7х7
![](scrins/2.png)
![](scrins/2.2.png)
Матрицы 9x9
![](scrins/3.png)
![](scrins/3.3.png)
Матрицы 11х11
![](scrins/4.png)
![](scrins/4.4.png)
Вывод: Параллельный алгоритм работает быстрее только при наличии большого количества операций. Если операций не так много, то обычный алгоритм справляется быстрее.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB