C# Stopwatch计时问题:替代Thread.Sleep实现游戏定时运行需求
解决C#游戏计时中Thread.Sleep阻塞的问题
嘿,踩坑了对吧?Thread.Sleep确实会搞崩游戏体验——它会直接阻塞当前主线程,游戏的渲染、输入响应全停了,肯定不是你想要的效果。下面给你几个实用的替代方案,完美解决这个问题:
方案1:用异步await + Task.Delay(通用C#方案)
这个方法不会阻塞主线程,后台等待时长到了再执行后续逻辑,游戏全程流畅运行:
async void StartGameTimer() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // 替换成你需要的设定时长,比如10秒 await Task.Delay(TimeSpan.FromSeconds(10)); stopWatch.Stop(); autoPlay = true; // 这里写停止游戏运行的逻辑,比如暂停游戏循环、清理资源等 }
说明:await会让这个方法暂时挂起,但主线程该干嘛干嘛——游戏渲染、用户输入都不受影响,等Task.Delay的时间到了,会自动回到这里执行后续代码。
方案2:利用游戏引擎内置计时器(推荐,适配游戏场景)
如果你用的是Unity这类游戏引擎,用自带的协程(Coroutine)是最贴合游戏开发流程的方式:
IEnumerator GameTimerCoroutine() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // 等待设定时长,比如10秒 yield return new WaitForSeconds(10); stopWatch.Stop(); autoPlay = true; // 执行停止游戏的逻辑 } // 启动协程的方式(比如在游戏初始化时调用) // StartCoroutine(GameTimerCoroutine());
其他引擎比如Godot也有类似的Timer节点或延迟调用API,原理都是让引擎帮你在后台计时,完全不占用主线程资源。
方案3:帧循环中检查Stopwatch(无依赖通用方案)
如果不想用异步或引擎API,可以在游戏的帧更新方法里每帧检查计时:
private Stopwatch _gameStopwatch; // 设定目标时长,比如10秒 private readonly TimeSpan _targetRunTime = TimeSpan.FromSeconds(10); // 启动计时的方法 void StartGameTimer() { _gameStopwatch = new Stopwatch(); _gameStopwatch.Start(); } // 在游戏的Update方法中(每帧都会被调用) void Update() { if (_gameStopwatch != null && _gameStopwatch.Elapsed >= _targetRunTime) { _gameStopwatch.Stop(); _gameStopwatch = null; // 防止重复触发 autoPlay = true; // 停止游戏运行的逻辑 } }
这个方式就是每帧“瞟一眼”计时器有没有到时间,完全不会阻塞游戏,适合所有C#游戏场景。
内容的提问来源于stack exchange,提问作者T.Evans
相关产品推荐
相关产品推荐

