C#: Асинхронность

Spread the love

Асинхронность в C# – это механизм, который позволяет выполнять операции в фоновом режиме, не блокируя основной поток выполнения программы. Он позволяет более эффективно использовать ресурсы системы и улучшить отзывчивость приложения, особенно в случае работы с вводом-выводом (I/O) или долгими операциями.

В C# асинхронность реализуется с помощью ключевых слов `async` и `await`, а также с использованием классов и методов из пространства имен `System.Threading.Tasks`.

Основные понятия в асинхронности C#:

1. `async` – ключевое слово, которое указывает, что метод содержит асинхронную операцию.

2. `await` – ключевое слово, которое используется внутри асинхронного метода для ожидания завершения другой асинхронной операции. Когда операция, помеченная как `await`, завершается, управление возвращается обратно в вызывающий метод.

3. `Task` – класс из пространства имен `System.Threading.Tasks`, представляющий асинхронную операцию, которая возвращает результат.

100000R, 12%, 1 year

4. `Task<T>` – параметризованный класс `Task`, представляющий асинхронную операцию, которая возвращает результат типа `T`.

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

“`csharp

using System;

using System.Threading.Tasks;

public class AsyncExample

{

    public async Task<string> GetStringAsync()

    {

        await Task.Delay(1000); // Асинхронная задержка в 1 секунду

        return “Hello, async!”;

    }

}

class Program

{

    static async Task Main()

    {

        AsyncExample example = new AsyncExample();

        string result = await example.GetStringAsync();

        Console.WriteLine(result); // Выведет “Hello, async!” после задержки

    }

}

“`

В этом примере метод `GetStringAsync` является асинхронным благодаря ключевому слову `async` и содержит асинхронную операцию задержки с помощью метода `Task.Delay()`. Операция `await example.GetStringAsync()` в методе `Main` ожидает завершения асинхронной операции `GetStringAsync`, а затем выводит результат.

Асинхронность особенно полезна при работе с сетью, файловой системой, базами данных или другими операциями, которые могут быть времязатратными и блокирующими. Вместо блокирования основного потока выполнения, асинхронные операции позволяют выполнять множество задач параллельно и повышают производительность приложения.

                            async & await

Асинхронность в C# реализуется с помощью ключевых слов `async` и `await`. Эти ключевые слова позволяют создавать асинхронные методы и ждать завершения асинхронных операций без блокировки основного потока выполнения.

Ключевое слово `async` используется для пометки методов, которые содержат асинхронные операции. Асинхронный метод может возвращать тип `Task`, `Task<T>` или `void`. Методы с возвращаемым типом `Task` или `Task<T>` представляют асинхронные операции, которые могут возвращать результат, а `void` используется, когда результат операции не требуется или обрабатывается другим способом.

Ключевое слово `await` используется внутри асинхронных методов для ожидания завершения других асинхронных операций. Когда код достигает оператора `await`, выполнение метода приостанавливается, и управление возвращается в вызывающий метод, пока асинхронная операция не завершится. После завершения операции управление возвращается обратно в асинхронный метод, и результат асинхронной операции (если есть) доступен для дальнейшей обработки.

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

“`csharp

using System;

using System.Threading.Tasks;

public class AsyncExample

{

    public async Task<string> GetStringAsync()

    {

        await Task.Delay(1000); // Асинхронная задержка в 1 секунду

        return “Hello, async!”;

    }

}

class Program

{

    static async Task Main()

    {

        AsyncExample example = new AsyncExample();

        string result = await example.GetStringAsync();

        Console.WriteLine(result); // Выведет “Hello, async!” после задержки

    }

}

“`

В этом примере метод `GetStringAsync` является асинхронным благодаря ключевому слову `async` и содержит асинхронную операцию задержки с помощью метода `Task.Delay()`. Операция `await example.GetStringAsync()` в методе `Main` ожидает завершения асинхронной операции `GetStringAsync`, а затем выводит результат.

Асинхронность с помощью `async` и `await` особенно полезна при работе с сетью, файловой системой, базами данных или другими операциями, которые могут быть времязатратными и блокирующими. Вместо блокирования основного потока выполнения, асинхронные операции позволяют выполнять множество задач параллельно и повышают производительность приложения.

                            Tasks

В C#, `Task` представляет асинхронную операцию или процесс, который выполняется в фоновом режиме. Он является частью пространства имен `System.Threading.Tasks` и предоставляет удобный способ работы с асинхронным программированием.

`Task` представляет логическое представление асинхронной операции и может возвращать результат или быть пустым (возвращать `void`). Когда асинхронная операция выполняется, `Task` может сообщить об успешном завершении операции, о наличии исключения или о том, что операция была отменена.

Рассмотрим пример асинхронного метода, возвращающего `Task<int>`:

“`csharp

using System;

using System.Threading.Tasks;

public class AsyncExample

{

    public async Task<int> LongRunningOperationAsync()

    {

        await Task.Delay(2000); // Асинхронная задержка в 2 секунды

        return 42;

    }

}

class Program

{

    static async Task Main()

    {

        AsyncExample example = new AsyncExample();

        Task<int> task = example.LongRunningOperationAsync();

        Console.WriteLine(“Ожидание завершения асинхронной операции…”);

        int result = await task;

        Console.WriteLine($”Результат асинхронной операции: {result}”);

    }

}

“`

В этом примере метод `LongRunningOperationAsync` является асинхронным благодаря ключевому слову `async` и содержит асинхронную операцию задержки с помощью метода `Task.Delay()`. Он возвращает `Task<int>`, что означает, что асинхронная операция вернет результат типа `int`.

В методе `Main`, когда вызывается `example.LongRunningOperationAsync()`, возвращается объект `Task<int>`, который представляет асинхронную операцию. Затем с помощью ключевого слова `await` происходит ожидание завершения этой операции, и результат асинхронной операции (значение 42) присваивается переменной `result`.

`Task` также позволяет обрабатывать ошибки и исключения, возникающие в ходе выполнения асинхронной операции, используя методы `ContinueWith`, `WhenAll`, `WhenAny` и другие.

Использование `Task` упрощает асинхронное программирование в C# и позволяет создавать эффективные и отзывчивые приложения, особенно при работе с долгими или блокирующими операциями, такими как сетевые запросы или обращения к базам данных.

                            Task Schedule

В C#, планировщик задач (`Task Scheduler`) – это часть механизма асинхронности, который управляет планированием и выполнением асинхронных операций в фоновом режиме. Планировщик задач определяет, как и когда асинхронные задачи будут выполняться на различных потоках или пулах потоков.

По умолчанию в C# используется планировщик задач, предоставляемый .NET Framework (или .NET Core). Он предоставляет следующие возможности:

1. Пул потоков: Планировщик задач использует пул потоков для выполнения асинхронных задач. Пул потоков представляет собой набор предварительно созданных потоков, которые могут повторно использоваться для выполнения различных задач. Это позволяет избежать создания новых потоков для каждой асинхронной операции, что улучшает производительность и уменьшает накладные расходы на создание потоков.

2. Планирование: Планировщик задач определяет, на каких потоках выполняются асинхронные операции. Это позволяет эффективно использовать ресурсы процессора и управлять приоритетами задач.

3. Контекст синхронизации: В некоторых случаях, когда необходимо выполнить асинхронную операцию в том же контексте (например, UI-поток) или контексте синхронизации (например, ASP.NET контекста), планировщик задач может автоматически обеспечивать такую возможность.

Пример использования планировщика задач:

“`csharp

using System;

using System.Threading.Tasks;

public class AsyncExample

{

    public async Task<int> LongRunningOperationAsync()

    {

        await Task.Delay(2000); // Асинхронная задержка в 2 секунды

        return 42;

    }

}

class Program

{

    static async Task Main()

    {

        AsyncExample example = new AsyncExample();

        Task<int> task = example.LongRunningOperationAsync();

        Console.WriteLine(“Ожидание завершения асинхронной операции…”);

        int result = await task;

        Console.WriteLine($”Результат асинхронной операции: {result}”);

    }

}

“`

В приведенном выше примере, когда вызывается метод `LongRunningOperationAsync()`, планировщик задач решает, на каком потоке выполнить асинхронную задачу. При использовании метода `await` операция может быть продолжена на том же или другом доступном потоке в зависимости от планировщика задач.

В общем случае, разработчикам не требуется управлять планировщиком задач напрямую, так как .NET Framework предоставляет оптимальные настройки по умолчанию. Однако, в некоторых специфических случаях может быть необходимо кастомизировать планировщик задач для оптимизации работы асинхронных операций.

                            Cаncellation Token

`CancellationToken` в C# – это механизм, который позволяет отменить выполняющуюся асинхронную операцию. Он является частью механизма асинхронности и используется для контроля и управления асинхронными задачами.

`CancellationToken` представляет токен отмены и содержит методы для проверки статуса отмены и запроса отмены асинхронной операции. При отмене операции можно выполнить соответствующие действия для завершения асинхронной задачи или возврата управления в вызывающий код.

Пример использования `CancellationToken`:

“`csharp

using System;

using System.Threading;

using System.Threading.Tasks;

public class AsyncExample

{

    public async Task<int> LongRunningOperationAsync(CancellationToken cancellationToken)

    {

        await Task.Delay(2000, cancellationToken); // Асинхронная задержка в 2 секунды с учетом токена отмены

        return 42;

    }

}

class Program

{

    static async Task Main()

    {

        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

        CancellationToken cancellationToken = cancellationTokenSource.Token;

        AsyncExample example = new AsyncExample();

        Task<int> task = example.LongRunningOperationAsync(cancellationToken);

        // Через некоторое время отменяем задачу

        cancellationTokenSource.Cancel();

        try

        {

            int result = await task;

            Console.WriteLine($”Результат асинхронной операции: {result}”);

        }

        catch (TaskCanceledException)

        {

            Console.WriteLine(“Операция была отменена.”);

        }

    }

}

“`

В этом примере метод `LongRunningOperationAsync` принимает `CancellationToken`, который используется в методе `Task.Delay` для асинхронной задержки. Если `CancellationToken` был отменен (например, вызовом `cancellationTokenSource.Cancel()`), операция будет отменена, и выполнение метода `LongRunningOperationAsync` будет прервано с исключением `TaskCanceledException`.

При использовании `CancellationToken`, важно проверять его статус внутри асинхронных методов и реагировать на отмену операции. Это позволяет предоставить более отзывчивое поведение и более точный контроль над асинхронными задачами.

`CancellationToken` обеспечивает безопасный и надежный механизм отмены асинхронных операций, особенно когда требуется обработать возможные сценарии отмены и прерывания работы.

Схема асинхронность

Spread the love

Добавить комментарий