14.UniTaskCompleitonSource

14.设置结果和取消


14.1 知识点

UniTaskCompleitonSource 的使用:设置结果与取消任务

在 Unity 开发中,使用异步编程可以有效提升应用的响应速度和用户体验。UniTask 是一个专为 Unity 设计的高性能异步库,它提供了类似于 C# Task 的功能,但更加轻量级且性能优化。本文将介绍如何使用 UniTaskCompletionSource 来手动控制异步任务的完成和取消。

什么是 UniTaskCompletionSource?

UniTaskCompletionSource<T> 是 UniTask 提供的一个工具类,允许开发者手动控制异步任务的完成、失败或取消。它类似于 .NET 中的 TaskCompletionSource<T>,但针对 Unity 环境进行了优化。

通过 UniTaskCompletionSource,我们可以在需要的地方创建一个未完成的任务,并在适当的时机手动设置其结果或取消状态,从而实现对异步流程的精确控制。

示例:设置结果和取消任务

以下示例演示了如何使用 UniTaskCompletionSource<string> 来创建一个可手动控制的异步任务,并通过按钮点击事件来设置任务结果或取消任务。

using UnityEngine;
using Cysharp.Threading.Tasks;
using System;

public class Lesson14_SetResultAndCancel : MonoBehaviour
{
    private UniTaskCompletionSource<string> _uniTaskCompletionSource;

    async void Start()
    {
        // 初始化任务源
        _uniTaskCompletionSource = new UniTaskCompletionSource<string>();

        try
        {
            // 等待任务完成
            string result = await _uniTaskCompletionSource.Task;
            Debug.Log("任务完成,结果为:" + result);
        }
        catch (OperationCanceledException)
        {
            Debug.Log("任务被取消");
        }
        catch (Exception ex)
        {
            Debug.LogError($"任务执行出错: {ex.Message}");
        }
    }

    void OnGUI()
    {
        // 创建设置值按钮
        if (GUI.Button(new Rect(540, 120, 120, 120), "设置值"))
        {
            // 设置任务结果
            _uniTaskCompletionSource.TrySetResult("任务执行成功!");
        }

        // 创建取消按钮
        if (GUI.Button(new Rect(540, 300, 120, 120), "取消任务"))
        {
            // 取消任务
            _uniTaskCompletionSource.TrySetCanceled();
        }
    }
}



在上述代码中:

  1. 初始化任务源:在 Start 方法中,创建了一个 UniTaskCompletionSource<string> 实例 _uniTaskCompletionSource

  2. 等待任务完成:使用 await _uniTaskCompletionSource.Task 来等待任务的完成。如果任务被取消,会捕获 OperationCanceledException 异常;如果发生其他异常,会进行相应的错误处理。

  3. 设置任务结果:在 OnGUI 方法中,创建了一个按钮,当点击该按钮时,调用 _uniTaskCompletionSource.TrySetResult("任务执行成功!") 来手动设置任务的结果。

  4. 取消任务:同样在 OnGUI 方法中,创建了另一个按钮,当点击该按钮时,调用 _uniTaskCompletionSource.TrySetCanceled() 来取消任务。

注意事项

  • 多次设置任务状态TrySetResultTrySetCanceledTrySetException 方法都是尝试设置任务的状态,如果任务已经完成或被取消,再次调用这些方法将不会生效。因此,确保在任务未完成时才调用这些方法。

  • 异常处理:在等待任务的过程中,建议使用 try-catch 块来捕获可能出现的异常,特别是 OperationCanceledException,以便正确处理任务取消的情况。

  • 线程安全UniTaskCompletionSource 的方法是线程安全的,可以在不同的线程中调用。但在 Unity 中,通常建议在主线程中操作 UI 和游戏对象。

通过上述示例和注意事项,我们可以在 Unity 中使用 UniTaskCompletionSource 来精确控制异步任务的完成和取消,从而编写出更为灵活和高效的异步代码。


14.2 知识点代码

Lesson14_设置结果和取消.cs

using UnityEngine;
using Cysharp.Threading.Tasks;
using System;

public class Lesson14_设置结果和取消 : MonoBehaviour
{
    private UniTaskCompletionSource<string> _uniTaskCompletionSource;

    async void Start()
    {
        // 初始化两个任务源
        _uniTaskCompletionSource = new UniTaskCompletionSource<string>();
        UniTask<string> stringUniTask = _uniTaskCompletionSource.Task;

        try
        {
            // 等待任务完成
            string stringResult = await _uniTaskCompletionSource.Task;
            Debug.Log("任务完成,结果为:" + stringResult);
        }
        catch (OperationCanceledException)
        {
            Debug.Log("任务被取消");
        }
        catch (Exception ex)
        {
            Debug.LogError($"任务执行出错: {ex.Message}");
        }
    }

    void OnGUI()
    {
        // 创建设置值按钮
        if (GUI.Button(new Rect(540, 120, 120, 120), "设置值"))
        {
            // 设置任务结果
            _uniTaskCompletionSource.TrySetResult("任务执行成功!");
        }

        // 创建取消按钮
        if (GUI.Button(new Rect(540, 300, 120, 120), "取消任务"))
        {
            // 设置任务取消
            _uniTaskCompletionSource.TrySetCanceled();
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏