C#中使用 async await TaskCompletionSource<T>实现异步逻辑同步写

Task、async 和 await 是 C# 中用于处理异步编程的关键概念。它们一起构成了异步编程的基础。

Task

Task 是表示异步操作的抽象,它属于 System.Threading.Tasks 命名空间。Task 可以表示已经完成的任务、正在运行的任务或者尚未开始的任务。通过 Task,可以执行异步操作、并发操作,以及异步等待任务完成。

async 和 await

async 和 await 关键字是异步编程的基础构造,用于简化异步代码的编写。它们通常一起使用,使得编写异步代码更加直观、易读。

async

关键字用于定义一个异步方法。异步方法可以包含 await 操作符,并且在异步执行期间可以被挂起,而不会阻塞调用线程。

await

await 操作符用于等待异步操作完成,并返回异步操作的结果。在 async 方法中,await 会将控制权返回给调用者,而不会阻塞线程,从而提高了程序的响应性。

TaskCompletionSource

TaskCompletionSource 是用于创建和控制 Task 实例的一种灵活的方式。通常情况下,Task 表示一个异步操作的结果,而 TaskCompletionSource 则允许你手动控制异步操作的完成。
tcs.SetResult(42) 来设置异步操作的结果
tcs.SetCanceled() 异步取消
tcs.SetException() 异常
TaskCompletionSource 成为一种强大的工具,用于自定义异步操作的实现和控制。

例子 直接上结果

在这里插入图片描述
以往的代码实现上都是请求一个异步操作挂载一个回调方法
使用Task可以轻松实现异步操作同步写代码

public class LoginLogic
{
   
   
    public async static void Call()
    {
   
   
        C2S_Login c2S_Login = new C2S_Login()
        {
   
   
            name = "wukong",
            password = "123456",
        };

        S2C_Login s2C_Login = await TaskLogic.Instance.Call<S2C_Login>(c2S_Login);
        Debug.LogError($"接收消息, id: {
     
     s2C_Login.id}, time: {
     
     s2C_Login.time}, location: {
     
     s2C_Login.location}");
        //这里直接处理后续逻辑
    }
}

public class Test : MonoBehaviour
{
   
   
    void Start()
    {
   
   
        LoginLogic.Call();
    }
}

代码实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading
C#中,如果你想在同步语句块(例如 `lock` 语句)中等待一个 `TaskCompletionSource<bool>` 的结果,你需要特别小心,因为直接在 `lock` 中使用 `await` 会导致编译错误或潜在的死锁问题。解决这个问题的常见方法是先退出锁,再进行异步等待。 以下是一个示例,展示如何安全地等待 `TaskCompletionSource<bool>` 被设置为 `true`: ```csharp private readonly object lockObj = new object(); private TaskCompletionSource<bool> connectTcs = new TaskCompletionSource<bool>(); public async Task WaitForConnectionAsync() { bool shouldWait; // 在锁内检查状态,决定是否需要等待 lock (lockObj) { // 假设我们只有在未连接时才需要等待 shouldWait = !connectTcs.Task.IsCompleted; } // 在锁外进行异步等待 if (shouldWait) { await connectTcs.Task.ConfigureAwait(false); // 等待任务完成 } // 此时 connectTcs.Task.Result 应该是 true if (connectTcs.Task.Result) { Console.WriteLine("连接成功!"); } else { Console.WriteLine("连接未成功。"); } } ``` ### 说明: - 在 `lock` 块中我们只检查是否需要等待,而不进行异步等待。 - `await connectTcs.Task.ConfigureAwait(false);` 用于避免捕获当前的同步上下文,防止潜在的死锁。 - 当 `connectTcs.SetResult(true);` 被调用时,等待的任务将完成,`await` 后的代码将继续执行。 ### 相关操作: 你可以通过以下方式设置 `TaskCompletionSource` 的结果: ```csharp connectTcs.SetResult(true); // 触发任务完成 ``` ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值