You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用回调完成任务?封装异步回调为Task返回结果的方法

将基于回调的异步操作封装为Task

要把这种回调式的异步方法封装成返回Task<bool>的形式,最标准的做法是用TaskCompletionSource<T>——它专门用来把传统回调模式转换为Task-based异步模式(TAP)。

实现步骤

  1. 创建TaskCompletionSource<bool>实例,它相当于一个"任务控制器",可以手动控制Task的完成状态和返回结果。
  2. 定义内部回调函数,在这个回调里根据业务逻辑判断操作成功/失败,然后通过TaskCompletionSource设置Task的结果。
  3. 调用原有的MoveTo方法传入内部回调,最后返回TaskCompletionSource的Task属性。

完整代码示例

// 封装的异步方法
public static Task<bool> MoveToAsync(Device device, Position position)
{
    var taskCompletionSource = new TaskCompletionSource<bool>();

    // 定义内部回调,捕获taskCompletionSource
    void CommandCompleteCallback(ulong taskID)
    {
        try
        {
            // 这里替换成你实际判断任务成功/失败的逻辑
            bool operationSucceeded = CheckTaskResult(taskID);

            // 用TrySetResult确保即使回调被多次触发也不会抛出异常
            taskCompletionSource.TrySetResult(operationSucceeded);
        }
        catch (Exception ex)
        {
            // 如果回调执行中出现异常,将异常绑定到Task上
            taskCompletionSource.TrySetException(ex);
        }
    }

    // 调用原方法传入回调
    device.MoveTo(position, CommandCompleteCallback);

    // 返回Task,外部可以用await等待结果
    return taskCompletionSource.Task;
}

// 示例:模拟判断任务结果的方法
private static bool CheckTaskResult(ulong taskID)
{
    // 这里写你实际的判断逻辑,比如根据taskID查询设备状态等
    return true; // 替换为真实结果
}

使用方式

封装完成后,就可以用异步/await语法来调用,代码更简洁易读:

// 在异步方法中调用
bool moveResult = await MoveToAsync(device, targetPosition);
if (moveResult)
{
    // 处理成功逻辑
}
else
{
    // 处理失败逻辑
}

注意事项

  • 用TrySetResult而非SetResult:如果设备的回调可能被意外多次触发,SetResult会抛出InvalidOperationException,TrySetResult会安全地忽略后续的设置操作。
  • 异常处理:务必在回调内部捕获异常并通过TrySetException绑定到Task,否则异常会在后台线程抛出,难以追踪。

内容的提问来源于stack exchange,提问作者Pablo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:42:09