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

C#异步编程:如何优雅判断Task任务完成状态(替代返回字符串方式)

优雅处理C#异步任务状态的方案

你当前用返回字符串判断异步任务状态的方式属于反模式,既不符合C#的异常处理设计原则,也缺乏类型安全性。以下是几种规范且优雅的实现方案:


方案一:利用原生Task+异常处理(推荐)

无返回值的Task本身就足够传递任务状态:await会在任务成功完成时继续执行后续代码,若任务出错则直接抛出异常。调用方通过try-catch即可区分成功/失败场景,这是C#异步编程的标准实践。

定义异步方法

public async Task UploadFileAsync(string filePath, string destBlobFolder)
{
    await blobClient.UploadAsync(filePath, destBlobFolder);
}

调用方代码

try
{
    await UploadFileAsync(file, destination);
    // 执行到此处说明任务成功完成
    Console.WriteLine("文件上传完成");
}
catch (Exception ex)
{
    // 捕获任务执行过程中抛出的异常,处理错误场景
    Console.WriteLine($"上传失败:{ex.Message}");
}

这种方式遵循"正常流程无分支,异常流程单独处理"的设计原则,代码简洁易读,且能保留完整的异常信息用于排查问题。


方案二:返回自定义状态对象(适合需额外信息的场景)

如果需要返回除成功/失败外的更多状态(如参数错误、权限不足),或需要携带错误详情、业务结果,可以定义类型安全的状态枚举和结果对象。

定义状态枚举与结果类

public enum OperationStatus
{
    Success,
    Failed,
    InvalidFilePath,
    PermissionDenied
}

public class OperationResult
{
    public OperationStatus Status { get; set; }
    public Exception? Error { get; set; }
    // 可扩展添加业务属性,如上传后的文件ID、数据库影响行数等
}

修改异步方法

public async Task<OperationResult> UploadFileAsync(string filePath, string destBlobFolder)
{
    if (!File.Exists(filePath))
    {
        return new OperationResult 
        { 
            Status = OperationStatus.InvalidFilePath,
            Error = new FileNotFoundException("指定文件不存在", filePath)
        };
    }

    try
    {
        await blobClient.UploadAsync(filePath, destBlobFolder);
        return new OperationResult { Status = OperationStatus.Success };
    }
    catch (UnauthorizedAccessException ex)
    {
        return new OperationResult 
        { 
            Status = OperationStatus.PermissionDenied,
            Error = ex
        };
    }
    catch (Exception ex)
    {
        return new OperationResult 
        { 
            Status = OperationStatus.Failed,
            Error = ex
        };
    }
}

调用方代码

var result = await UploadFileAsync(file, destination);
switch (result.Status)
{
    case OperationStatus.Success:
        Console.WriteLine("上传完成");
        break;
    case OperationStatus.InvalidFilePath:
        Console.WriteLine($"文件错误:{result.Error?.Message}");
        break;
    case OperationStatus.PermissionDenied:
        Console.WriteLine("权限不足,无法上传");
        break;
    default:
        Console.WriteLine($"上传失败:{result.Error?.Message ?? "未知错误"}");
        break;
}

该方案类型安全,避免了字符串硬编码的拼写错误,同时能传递更丰富的业务上下文。


方案三:直接检查Task属性(适合非阻塞场景)

如果不需要立即等待任务完成,而是要在后续流程中检查任务状态,可以保留原Task返回类型,通过Task的内置属性判断:

var uploadTask = UploadFileAsync(file, destination);
// 并行执行其他操作
await ProcessOtherWorkAsync();

// 检查任务状态
if (uploadTask.IsCompletedSuccessfully)
{
    Console.WriteLine("上传完成");
}
else if (uploadTask.IsFaulted)
{
    Console.WriteLine($"上传失败:{uploadTask.Exception?.InnerException?.Message}");
}
else if (uploadTask.IsCanceled)
{
    Console.WriteLine("上传被取消");
}

注意:这种方式仅适合不需要立即阻塞等待结果的场景,若最终需要确保任务完成,仍建议使用await+try-catch的组合。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:41:17