Nenhuma descrição

V.Yakimova 1f442532b6 бамбуковый бамбук 9 meses atrás
.idea dd78004f9b baobab 9 meses atrás
gitignore.txt b1eb6d37ef что это 10 meses atrás
readme.md 1f442532b6 бамбуковый бамбук 9 meses atrás

readme.md

Конспект лекции "Многопоточность" :()=[,`][]=

// Задачи и класс Task

Первый способ создание объекта Task и вызов у него метода Start:

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();
Task2 is executed
Task1 is executed
Task3 is executed

Process finished with exit code 0.

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

esempio

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

Process finished with exit code 0.

// 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
Введите число: 
7
Квадрат числа равен 49
Факториал равен 720
Конец метода FactorialAsync

Process finished with exit code 0.

esempio - чтение-запись файла:

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";

    // hello.txt - файл, который будет записываться и считываться
    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

Process finished with exit code 0.

мы сами можем определить асинхронную операцию, используя метод 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));
}
Некоторая работа
Факториал равен 120
Факториал равен 720

Process finished with exit code 0.

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

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

Process finished with exit code 0.

// Возвращение результата из асинхронного метода

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));
}
Факториал равен 120
Факториал равен 720
Некоторая работа  

Process finished with exit code 0.

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

Process finished with exit code 0.

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

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

Process finished with exit code 0.

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

Обработка ошибок в асинхронных методах, использующих ключевые слова async и await, имеет свои особенности.

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

Process finished with exit code 0.

поломанный код

static async void FactorialAsync(int n)
{
    Task task = null;
    try
    {
        task = Task.Run(()=>Factorial(n));
        await task;
    }
    catch (Exception ex)
    {
        Console.WriteLine(task.Exception.InnerException.Message);
        Console.WriteLine($"IsFaulted: {task.IsFaulted}");
    }
}
error

эксепшен не эксепшен, вывод с неба упал

static async Task DoMultipleAsync()
{
    Task allTasks = null;
 
    try
    {
        Task t1 = Task.Run(()=>Factorial(-3));
        Task t2 = Task.Run(() => Factorial(-5));
        Task t3 = Task.Run(() => Factorial(-10));
 
        allTasks = Task.WhenAll(t1, t2, t3);
        await allTasks;
    }
    catch (Exception ex)
    {
        Console.WriteLine("Исключение: " + ex.Message);
        Console.WriteLine("IsFaulted: " + allTasks.IsFaulted);
        foreach (var inx in allTasks.Exception.InnerExceptions)
        {
            Console.WriteLine("Внутреннее исключение: " + inx.Message);
        }
    }
}
Исключение: -3 : число не должно быть меньше 1
IsFaulted: True
Внутреннее исключение: -3: число не должно быть меньше 1
Внутреннее исключение: -5: число не должно быть меньше 1
Внутреннее исключение: -10: число не должно быть меньше 1

никакой возможности нет, это афера

static async void FactorialAsync(int n)
{
    try
    {
        await Task.Run(() => Factorial(n)); ;
    }
    catch (Exception ex)
    {
        await Task.Run(()=>Console.WriteLine(ex.Message));
    }
    finally
    {
        await Task.Run(() => Console.WriteLine("await в блоке finally"));
    }
}
error

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

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
Операция прервана токеном

Process finished with exit code 0.