LinqPad 5如何实现超时自动返回默认值的Util.ReadLine
LinqPad 5 实现带超时的Util.ReadLine功能
更新:在LinqPad 5版本中,需要实现带超时功能的Util.ReadLine:等待用户输入指定时长后,若未收到输入则自动返回默认值。
现有同步实现代码
double mins = 0.0; var input = Util.ReadLine("Timeout after how many minutes?", "360", new[] { "60", "120", "180", "240" }); double.TryParse(input, out mins);
初始异步写法的问题
尝试使用Util.ReadLineAsync搭配Wait实现超时的代码如下:
var input = Util .ReadLineAsync("Timeout after how many minutes?", "360", new[] { "60", "120", "180", "240" }) .Wait(TimeSpan.FromSeconds(30));
该写法存在明显缺陷:Task.Wait()返回值为布尔类型,仅能标识等待是否超时,无法获取实际用户输入结果,同时阻塞调用线程容易引发死锁。
正确实现方案
通过Task.WhenAny同时等待输入任务和超时任务,哪个任务先完成就执行对应逻辑即可。LinqPad 5原生支持async/await语法,直接将以下代码放入查询窗口即可运行:
double mins = 0.0; // 可自定义配置 var timeout = TimeSpan.FromSeconds(30); const string defaultValue = "360"; var candidateOptions = new[] { "60", "120", "180", "240" }; var readInputTask = Util.ReadLineAsync("Timeout after how many minutes?", defaultValue, candidateOptions); var timeoutTask = Task.Delay(timeout); var completedTask = await Task.WhenAny(readInputTask, timeoutTask); string finalInput; if (completedTask == timeoutTask) { // 触发超时逻辑,使用默认值,释放未完成的输入任务 readInputTask.Dispose(); finalInput = defaultValue; Console.WriteLine($"\n等待输入超时,已自动采用默认值:{defaultValue}"); } else { // 获取用户输入结果 finalInput = await readInputTask; } double.TryParse(finalInput, out mins); // LinqPad内置方法输出结果 mins.Dump("最终生效的分钟配置");
注意事项
- 禁止使用
Wait()、Result阻塞异步任务,LinqPad查询默认提供异步上下文,直接使用await不会出现死锁问题 - 超时触发后需主动Dispose未完成的输入任务,避免残留的输入监听器占用资源
- 超时时间、默认值、输入候选项均统一放在代码开头配置段,修改时无需调整核心逻辑
- 该实现完全基于LinqPad 5内置API,无需引入任何第三方依赖
内容的提问来源于stack exchange,提问作者MadeAThing
相关产品推荐
相关产品推荐

