Чернов Данил И-21

dpokatski 6a9dec995a lab9 10 months ago
lab1 1c21483e31 lab6 10 months ago
lab2 030b5c7a7d lab2 11 months ago
lab3 b095883763 lab3 11 months ago
lab4 ae1ca97f06 lab4 11 months ago
lab5 80dcdc3d8c lab5 11 months ago
lab6 1c21483e31 lab6 10 months ago
lab7 da1c3eed1e lab7 10 months ago
lab8 5e837b40c3 lab8 10 months ago
lab9 6a9dec995a lab9 10 months ago
readme.md 6a9dec995a lab9 10 months ago

readme.md

Lab 9 Введение в многопоточность

Параллельное программирование и библиотека TPL

System.Threading.Tasks

Task task = new Task(
    () => Console.WriteLine("Hello Task!")
);
task.Start();
Process finished with exit code 0.

Task.Factory.StartNew()

Task task = Task.Factory.StartNew(
    () => Console.WriteLine("Hello Task!")
);
Process finished with exit code 0.

Task.Run()

Task task = Task.Run(
    () => Console.WriteLine("Hello Task!")
);
Process finished with exit code 0.

Рассмотрим пример асинхронного метода:

using System;
using System.Threading.Tasks;
 
Task task1 = new Task(
    () => Console.WriteLine("Task1 is executed"));
task1.Start();

Task task2 = Task.Factory.StartNew(
    () => Console.WriteLine("Task2 is executed"));

Task task3 = Task.Run(
    () => Console.WriteLine("Task3 is executed"));
    
Console.ReadLine();
Task1 is executed
Task3 is executed
Task2 is executed

Ожидание задачи

using System;
using System.Threading;
 
Task task = new Task(Display);
task.Start();
    
Console.WriteLine(
    "Завершение метода Main");

Console.ReadLine();

static void Display()
{
    Console.WriteLine(
        "Начало работы метода Display");

    Console.WriteLine(
        "Завершение работы метода Display");
}
Завершение метода Main
Начало работы метода Display    
Завершение работы метода Display

Aсинхронное программирование. Асинхронные методы, async и await

using System;
using System.Threading;
using System.Threading.Tasks;

FactorialAsync();   

Console.WriteLine(
    "Введите число: ");

int n = Int32.Parse(Console.ReadLine());

Console.WriteLine(
    $"Квадрат числа равен {n * n}");
    
Console.Read();


static void Factorial()
{
    int result = 1;
    for(int i = 1; i <= 6; i++)
    {
        result *= i;
    }
    Thread.Sleep(8000);
    Console.WriteLine(
        $"Факториал равен {result}");
}

static async void FactorialAsync()
{
    Console.WriteLine(
        "Начало метода FactorialAsync");
    
    await Task.Run(()=>Factorial());

    Console.WriteLine(
        "Конец метода FactorialAsync");
}
Начало метода FactorialAsync
Введите число: 
3
Квадрат числа равен 9
Факториал равен 720
Конец метода FactorialAsync
using System;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
 
ReadWriteAsync();
    
Console.WriteLine("Некоторая работа");
Console.Read();


static async void ReadWriteAsync()
{
    string s = "Hello world! One step at a time";

    using (StreamWriter writer = new StreamWriter("hello.txt", false))
    {
        await writer.WriteLineAsync(s);  
    }
    using (StreamReader reader = new StreamReader("hello.txt"))
    {
        string result = await reader.ReadToEndAsync();  
        Console.WriteLine(result);
    }
} 

Hello world! One step at a time

Task.Run()

static void Factorial()
{
    int result = 1;
    for (int i = 1; i <= 6; i++)
    {
        result *= i;
    }
    Thread.Sleep(8000);
    Console.WriteLine($"Факториал равен {result}");
}
static async void FactorialAsync()
{
    await Task.Run(()=>Factorial()); 
}
Process finished with exit code 0.

Можно определить асинхронную операцию с помощью лямбда-выражения:

static async void FactorialAsync()
{
    await Task.Run(() =>
    {
        int result = 1;
        for (int i = 1; i <= 6; i++)
        {
            result *= i;
        }
        Thread.Sleep(8000);
        Console.WriteLine($"Факториал равен {result}");
    });
}
Process finished with exit code 0.

Передача параметров в асинхронную операцию

using System;
using System.Threading;
using System.Threading.Tasks;
 

FactorialAsync(5);
FactorialAsync(6);
Console.WriteLine("Некоторая работа");
Console.Read();


static void Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    Thread.Sleep(5000);
    Console.WriteLine($"Факториал равен {result}");
}
static async void FactorialAsync(int n)
{
    await Task.Run(()=>Factorial(n));
}
Некоторая работа
Факториал равен 720
Факториал равен 120

Получение результата из асинхронной операции

using System;
using System.Threading;
using System.Threading.Tasks;
 

FactorialAsync(5);
FactorialAsync(6);
Console.Read();


static int Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
static async void FactorialAsync(int n)
{
    int x = await Task.Run(()=>Factorial(n));
    Console.WriteLine($"Факториал равен {x}");
}
Факториал равен 120
Факториал равен 720

Void

static void Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    Console.WriteLine($"Факториал равен {result}");
}

static async void FactorialAsync(int n)
{
    await Task.Run(()=>Factorial(n));
}
Process finished with exit code 0.

Task

using System;
using System.Threading.Tasks;

FactorialAsync(5);
FactorialAsync(6);
Console.WriteLine("Некоторая работа");
Console.Read();

static void Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    Console.WriteLine($"Факториал равен {result}");
}
    
static async Task FactorialAsync(int n)
{
    await Task.Run(()=>Factorial(n));
}
Некоторая работа
Факториал равен 720
Факториал равен 120

Task

using System;
using System.Threading.Tasks;

int n1 = await FactorialAsync(5);
int n2 = await FactorialAsync(6);
Console.WriteLine($"n1={n1}  n2={n2}");
Console.Read();

static int Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
static async Task<int> FactorialAsync(int n)
{
    return await Task.Run(()=>Factorial(n));
}
n1=120  n2=720

Последовательный и параллельный вызов асинхронных операций

using System;
using System.Threading.Tasks;

FactorialAsync();
Console.Read();

static void Factorial(int n)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    Console.WriteLine($"Факториал числа {n} равен {result}");
}

static async void FactorialAsync()
{
    await Task.Run(() => Factorial(4));
    await Task.Run(() => Factorial(3));
    await Task.Run(() => Factorial(5));
}
Факториал числа 4 равен 24
Факториал числа 3 равен 6  
Факториал числа 5 равен 120

Обработка ошибок в асинхронных методах

using System;
using System.Threading;
using System.Threading.Tasks;
 

FactorialAsync(-4);
FactorialAsync(6);
Console.Read();

static void Factorial(int n)
{
    if (n < 1)
        throw new Exception($"{n} : число не должно быть меньше 1");
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    Console.WriteLine($"Факториал числа {n} равен {result}");
}
    
static async void FactorialAsync(int n)
{
    try
    {
        await Task.Run(() => Factorial(n));
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}
Факториал числа 6 равен 720
-4 : число не должно быть меньше 1

Отмена асинхронных операций

using System;
using System.Threading;
using System.Threading.Tasks;
 
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
FactorialAsync(6, token);
Thread.Sleep(3000);
cts.Cancel();
Console.Read();

static void Factorial(int n, CancellationToken token)
{
    int result = 1;
    for (int i = 1; i <= n; i++)
    {
        if (token.IsCancellationRequested)
        {
            Console.WriteLine(
                "Операция прервана токеном");
            return;
        }
        result *= i;
        Console.WriteLine(
            $"Факториал числа {i} равен {result}");
        Thread.Sleep(1000);
    }
}
static async void FactorialAsync(int n, CancellationToken token)
{
    if(token.IsCancellationRequested)
        return;
    await Task.Run(()=>Factorial(n, token));
}
Факториал числа 1 равен 1
Факториал числа 2 равен 2
Факториал числа 3 равен 6
Операция прервана токеном