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

如何在.NET 4.0中替代Task.WhenAny()实现双任务协同逻辑

在.NET 4.0中实现后台计算+每秒心跳的逻辑

针对你在.NET 4.0中模拟新版Task.WhenAny+后台计算+心跳的需求,我们可以利用.NET 4.0原生的Task和WaitHandle机制来实现,完全不需要第三方库。下面是具体的思路和代码实现:

核心思路

  1. 替代Task.Run:用.NET 4.0自带的Task.Factory.StartNew启动后台计算任务,这是当时启动异步任务的标准方式。
  2. 模拟Task.Delay:通过TaskCompletionSource<T>封装一个延迟完成的Task,内部用Timer实现非阻塞式的延迟,避免浪费线程资源。
  3. 模拟Task.WhenAny:获取两个Task的AsyncWaitHandle,用WaitHandle.WaitAny等待任意一个句柄触发,以此判断是计算任务完成还是心跳时间到了。

完整实现代码

using System;
using System.Threading;
using System.Threading.Tasks;

public class CalculationService
{
    // 模拟.NET 4.0版本的Task.Delay
    private static Task Delay(int millisecondsDelay)
    {
        var tcs = new TaskCompletionSource<bool>();
        var timer = new Timer(_ =>
        {
            tcs.TrySetResult(true);
        }, null, millisecondsDelay, Timeout.Infinite);
        
        // 任务完成后自动释放Timer,避免内存泄漏
        return tcs.Task.ContinueWith(_ => timer.Dispose());
    }

    public void StartCalculationAndHeartbeats()
    {
        // 替代Task.Run启动计算任务
        var calculationTask = Task.Factory.StartNew(() => DoTheCalculation());

        while (true)
        {
            // 创建每秒一次的心跳延迟任务
            var heartbeatTask = Delay(1000);

            // 获取两个任务的等待句柄,用于模拟Task.WhenAny
            var waitHandles = new[]
            {
                calculationTask.AsyncWaitHandle,
                heartbeatTask.AsyncWaitHandle
            };

            // 等待任意一个任务完成
            int completedIndex = WaitHandle.WaitAny(waitHandles);

            // 检查计算任务状态:完成或故障都需要终止循环并返回结果
            if (calculationTask.IsCompleted || calculationTask.IsFaulted)
            {
                SendResultToClient();
                break;
            }

            // 如果是心跳任务完成,发送心跳消息
            if (completedIndex == 1)
            {
                SendHeartbeatToClient();
            }
        }
    }

    // ------------------- 业务逻辑示例方法 -------------------
    private void DoTheCalculation()
    {
        // 模拟耗时计算,比如持续5秒
        Thread.Sleep(5000);
    }

    private void SendResultToClient()
    {
        Console.WriteLine("计算完成,发送结果给客户端");
    }

    private void SendHeartbeatToClient()
    {
        Console.WriteLine("发送心跳给客户端");
    }
}

关键细节说明

  • Delay方法的高效性:用Timer而非Thread.Sleep实现延迟,不会阻塞线程池线程,更适合高并发场景,且任务完成后自动释放Timer资源,避免内存泄漏。
  • WaitHandle.WaitAny的作用:这是.NET 4.0原生支持的“等待任意操作完成”的方式,通过Task的AsyncWaitHandle将异步任务的完成事件转化为可等待的信号,完美模拟Task.WhenAny的核心逻辑。
  • 任务状态的严谨检查:每次等待后都会检查计算任务的状态,无论是正常完成还是异常故障,都会终止循环并向客户端发送结果,保证逻辑的完整性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:49:19