C#代码实现延时的四种常用方法

Owen
Owen
发布时间:2026-10-16 | 6人浏览过
原创

C#中实现代码延时有多种方式,包括基于异步任务的 Task.Delay、同步阻塞的 Thread.Sleep、手动轮询时间差以及定时器逻辑。本文汇总了这四种常见实现的具体代码与注意事项,适用于不同的业务场景。

使用 Task.Delay 实现异步延时

这是最推荐的现代 C# 异步处理方式。它不会阻塞当前线程,而是将控制权交还调度器,等待指定时间后恢复执行。

以下代码演示了两种常见的调用方式:

  1. 方式一:直接在委托中使用 await
    利用 Task.Run 配合匿名异步委托,内部直接使用 await Task.Delay(3000) 实现3秒延时。
  2. 方式二:调用外部异步方法
    将延时逻辑封装为独立的 async 方法 task_YS,通过 Task.Run 启动。
using System;
using System.Threading.Tasks;

namespace csharpYS
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Mian方法第一次输出...");
            #region 第一种形式 
            var task_1 = Task.Run(async delegate
            {
                await Task.Delay(3000);
                Console.WriteLine("3秒后执行,方式一 输出语句...");
                return "异步执行result"; //可以得到一个返回值(int,bool,string都试了)
            });
            #endregion

            Console.WriteLine("Mian方法第二次输出,调用延时...");
            //注意:此时 task_1 尚未完成,Status可能为 RanToCompletion 或其他状态
            Console.WriteLine("task_1 的 Status:{0}, 结果: {1}",task_1.Status, task_1.Result);
            Console.WriteLine("第一种形式,延时结束...");

            #region 第二种形式
            Task task_2 = Task.Run(task_YS);
            //task_2.Wait();  //注释打开则等待task_2延时,注释掉则不等待
            #endregion

            Console.WriteLine("Mian方法最后一次输出,Main方法结束...");
            Console.ReadKey();
        }

        public static async Task task_YS()
        {
            await Task.Delay(5000);
            Console.WriteLine("5秒后执行,方式二 输出语句...");
        }
    }
}

运行结果说明:
当未调用 Wait() 时(即默认情况),主线程会立即执行后续打印语句,而后台任务在3秒或5秒后执行并输出结果,如图一所示。

对比:
如果取消注释 task_2.Wait(),主线程将在该点阻塞等待直到 task_2 执行完毕,行为上类似同步等待,但依然优于直接挂起整个应用进程的情况。

使用 Thread.Sleep 实现同步阻塞延时

如果你需要简单的同步延时,且不希望涉及异步上下文,可以使用 Thread.Sleep。它会阻塞当前所在的线程,直到时间到期。

这种方法适合控制台快速测试或非关键路径的简单延迟,但在高并发服务器应用中需谨慎使用,因为它会占用线程资源。

using System;
using System.Threading;

namespace ExceptionDeme
{
    class ThreadDemo
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main方法开始执行...");
            // 创建新线程执行下载模拟任务
            Thread threadA = new Thread(DownLoadFile);
            threadA.Start();
            
            Console.WriteLine("Main方法执行结束...");
            Console.ReadKey();
        }

        static void DownLoadFile()
        {
            Console.WriteLine("开始下载,此协程的Id是:" + Thread.CurrentThread.ManagedThreadId);
            // 模拟耗时操作,阻塞当前线程2秒
            Thread.Sleep(2000);
            Console.WriteLine("下载完成");
        }
    }
}

运行上述代码,可以看到新创建的线程ID与主线程不同,且在主线程结束后,子线程仍会继续运行并完成2秒的延时输出:

使用计时器/轮询方式实现延时

在某些特定场景下(如兼容旧版框架或特殊控制逻辑),可以通过记录起始时间和当前时间的差值来实现延时。这种方法本质上是忙等待(Busy Wait)或轻度轮询。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Czhenya ... Main Start");
        WaitFunctions(2); // 延时2秒
        Console.WriteLine("Czhenya ... Main End");
    }
    
    public static void WaitFunctions(int waitTime)
    {
        if (waitTime <= 0) return;

        Console.WriteLine("开始执行 ...");
        DateTime nowTimer = DateTime.Now;
        int interval = 0;
        
        // 循环检查时间差
        while (interval < waitTime)
        {
            TimeSpan spand = DateTime.Now - nowTimer;
            interval = spand.Seconds;
        }

        Console.WriteLine(waitTime + "秒后继续 ...");
    }
}

注意:
这种方式使用 DateTime.Now 获取秒级差异。如果需要更精确的微秒级控制,建议改用 Stopwatch 类并判断 TotalMilliseconds。此外,在空循环中让CPU持续计算会消耗少量处理器资源,不如 Task.Delay 或 Thread.Sleep 高效。

以上就是C#代码延时的详细内容,更多关于C#异步与时序控制的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表