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

.NET 7中如何用Task实现带超时的多设备异步初始化?

.NET 7 多设备初始化的Task实现方案

核心思路

  • 为每个设备初始化任务单独添加超时控制,避免单个设备无响应阻塞整体流程
  • 统一收集所有任务的执行结果(成功、失败、超时),而非依赖Task.WhenAll的默认异常抛出逻辑
  • 根据最终结果集展示对应UI:全成功展示成功界面,否则区分展示失败/超时设备

具体实现代码

定义基础模型

// 设备信息模型
public class DeviceInfo
{
    public string DeviceId { get; set; } = string.Empty;
    // 可添加其他设备属性,如名称、IP等
}

// 初始化结果状态枚举
public enum InitResultStatus
{
    Success,   // 初始化成功
    Failed,    // 初始化失败(抛出异常)
    Timeout    // 初始化超时
}

// 设备初始化结果模型
public class DeviceInitResult
{
    public string DeviceId { get; set; } = string.Empty;
    public InitResultStatus Status { get; set; }
    public Exception? Exception { get; set; } // 失败时存储异常信息
}

模拟设备初始化方法

// 模拟真实的设备初始化逻辑,可能抛出异常或耗时过长
private async Task InitializeDeviceAsync(DeviceInfo device)
{
    var random = new Random();
    // 模拟初始化耗时
    await Task.Delay(random.Next(1000, 5000));

    // 模拟20%的初始化失败概率
    if (random.Next(10) < 2)
    {
        throw new InvalidOperationException($"硬件检测失败");
    }
}

带超时的任务包装方法

// 为单个设备初始化任务添加超时控制,并返回统一结果
private async Task<DeviceInitResult> ExecuteInitWithTimeoutAsync(DeviceInfo device, int timeoutMs)
{
    var initTask = InitializeDeviceAsync(device);
    var delayTask = Task.Delay(timeoutMs);

    // 等待初始化任务或超时任务先完成
    var completedTask = await Task.WhenAny(initTask, delayTask);

    if (completedTask == delayTask)
    {
        // 超时情况
        return new DeviceInitResult
        {
            DeviceId = device.DeviceId,
            Status = InitResultStatus.Timeout
        };
    }

    try
    {
        // 等待初始化任务完成,捕获异常
        await initTask;
        return new DeviceInitResult
        {
            DeviceId = device.DeviceId,
            Status = InitResultStatus.Success
        };
    }
    catch (Exception ex)
    {
        // 初始化失败情况
        return new DeviceInitResult
        {
            DeviceId = device.DeviceId,
            Status = InitResultStatus.Failed,
            Exception = ex
        };
    }
}

主流程控制

// 批量处理设备初始化,并根据结果更新UI
public async Task ProcessDeviceInitializationAsync(List<DeviceInfo> devices, int timeoutMs = 3000)
{
    // 创建所有带超时控制的初始化任务
    var initTasks = devices.Select(device => ExecuteInitWithTimeoutAsync(device, timeoutMs)).ToList();

    // 等待所有任务完成,收集全部结果
    var allResults = await Task.WhenAll(initTasks);

    // 分类统计结果
    var successDevices = allResults.Where(r => r.Status == InitResultStatus.Success).Select(r => r.DeviceId);
    var failedResults = allResults.Where(r => r.Status == InitResultStatus.Failed);
    var timeoutDevices = allResults.Where(r => r.Status == InitResultStatus.Timeout).Select(r => r.DeviceId);

    // 根据结果更新UI(此处用控制台输出模拟,实际项目替换为UI操作)
    if (!failedResults.Any() && !timeoutDevices.Any())
    {
        Console.WriteLine("所有设备初始化成功!");
        // 展示成功UI逻辑
    }
    else
    {
        if (failedResults.Any())
        {
            Console.WriteLine("初始化失败的设备:");
            foreach (var result in failedResults)
            {
                Console.WriteLine($"- {result.DeviceId}:{result.Exception?.Message}");
            }
        }

        if (timeoutDevices.Any())
        {
            Console.WriteLine("初始化超时的设备:");
            foreach (var deviceId in timeoutDevices)
            {
                Console.WriteLine($"- {deviceId}");
            }
        }
        // 展示错误UI逻辑
    }
}

关键逻辑说明

  1. 超时控制:通过Task.WhenAny对比初始化任务和延迟任务,优先完成的任务决定当前设备的状态,避免单个设备无响应阻塞全局流程。
  2. 结果收集:使用Task.WhenAll等待所有任务完成,确保能获取每个设备的最终状态,不会因单个任务异常中断整体流程。
  3. 状态区分:通过自定义DeviceInitResult模型,清晰区分成功、失败、超时三种状态,便于后续UI展示逻辑的编写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:18:10