← Назад к вопросам

Как выглядит асинхронный метод?

1.0 Junior🔥 111 комментариев
#C# и ООП#Асинхронность и многопоточность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Развёрнутый ответ про асинхронные методы в C# для Unity

В контексте разработки на Unity с использованием C#, асинхронный метод — это метод, объявленный с модификатором async и обычно возвращающий Task, Task<T> или ValueTask<T>. Такой метод предназначен для неблокирующего выполнения операций, которые могут занять значительное время (например, загрузка ресурсов, сетевые запросы, сложные вычисления).

Базовый синтаксис асинхронного метода

using UnityEngine;
using System.Threading.Tasks;

public class AsyncExample : MonoBehaviour
{
    // Простейший асинхронный метод без возвращаемого значения
    async Task MyAsyncMethod()
    {
        // Асинхронная операция с использованием await
        await Task.Delay(1000);
        Debug.Log("Метод завершён после задержки");
    }

    // Асинхронный метод, возвращающий результат
    async Task<int> CalculateAsync()
    {
        await Task.Yield(); // Уступаем поток, чтобы не блокировать кадр
        int result = 0;
        // Имитируем длительную операцию
        for (int i = 0; i < 1000000; i++)
        {
            result += i % 100;
        }
        return result;
    }

    // Асинхронный метод, который можно вызвать из Unity
    async void Start()
    {
        Debug.Log("Начало асинхронной операции");
        await MyAsyncMethod();
        int value = await CalculateAsync();
        Debug.Log($"Результат вычисления: {value}");
    }
}

Ключевые характеристики асинхронных методов

  • Модификатор async — обязателен в объявлении метода. Он указывает компилятору, что метод содержит асинхронные операции и может использовать await.

  • Ключевое слово await — используется внутри метода для приостановки его выполнения до завершения асинхронной операции, при этом не блокируя основной поток.

  • Типы возвращаемых значений:

    • Task — для методов, не возвращающих результат
    • Task<T> — для методов, возвращающих результат типа T
    • async voidтолько для обработчиков событий, в Unity это часто Start(), OnClick() и подобные
    • ValueTask<T> — оптимизированная версия для случаев, когда результат часто доступен синхронно

Практический пример из разработки игр

using UnityEngine;
using UnityEngine.Networking;
using System.Threading.Tasks;

public class ResourceLoader : MonoBehaviour
{
    async void Start()
    {
        // Асинхронная загрузка текстуры из сети
        Texture2D texture = await LoadTextureAsync("https://example.com/image.png");
        
        if (texture != null)
        {
            GetComponent<Renderer>().material.mainTexture = texture;
            Debug.Log("Текстура успешно загружена и применена");
        }
    }

    async Task<Texture2D> LoadTextureAsync(string url)
    {
        using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url))
        {
            // Отправляем асинхронный запрос
            var operation = request.SendWebRequest();
            
            // Ждём завершения запроса без блокировки основного потока
            while (!operation.isDone)
            {
                await Task.Yield(); // Позволяет играть анимациям и обрабатывать ввод
                
                // Можно обновлять UI прогресса
                Debug.Log($"Прогресс загрузки: {operation.progress:P}");
            }

            if (request.result == UnityWebRequest.Result.Success)
            {
                return DownloadHandlerTexture.GetContent(request);
            }
            else
            {
                Debug.LogError($"Ошибка загрузки: {request.error}");
                return null;
            }
        }
    }
}

Важные особенности для Unity-разработки

  • Использование UniTask — многие опытные разработчики предпочитают библиотеку UniTask вместо стандартных Task, так как она лучше интегрирована с циклом обновления Unity и имеет оптимизации для разработки игр:
using Cysharp.Threading.Tasks;

async UniTaskVoid LoadGameSceneAsync()
{
    await Resources.LoadAsync<GameObject>("Prefabs/Character");
    await SceneManager.LoadSceneAsync("GameScene").ToUniTask();
}
  • Отмена операций — асинхронные методы должны поддерживать CancellationToken для корректной отмены:
async Task LoadWithCancellation(CancellationToken token)
{
    try
    {
        await Task.Delay(5000, token);
        // Если token отменён, Task.Delay выбросит OperationCanceledException
    }
    catch (OperationCanceledException)
    {
        Debug.Log("Загрузка отменена");
    }
}
  • Осторожность с async void — такие методы не позволяют обработать исключения или дождаться их завершения. В Unity их следует использовать только для методов жизненного цикла или обработчиков событий UI.

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

Как выглядит асинхронный метод? | PrepBro