当前位置: 首页 > news >正文

C# 方法执行超时策略

使用Task的等待机制来实现。

同步方法使用Task的实例方法wait() 设置执行等待时长;

异步方法则用Task.WhenAny()方法,与delay等待做比较;

注意:等待超时后,只是返回了默认值,实际调用的方法并未中断(即执行原方法的线程仍在执行,.NET中不能强制终止正在执行的线程),一定要注意确保数据唯一性。比如数据同步接口,方法内功能:【推送某个状态给其他系统成功后,再更新本地数据库标识】,如果该方法有超时策略,方法超时返回默认值时,程序并不清楚该方法是否执行成功(超时不代表失败)。如果是循环执行的线程,可以使用cts.Token.IsCancellationRequested来退出。

using System;
using System.Threading;
using System.Threading.Tasks;namespace AspCoreWebApiTest.Common
{public class OverTimeHandler{/// <summary>/// 同步执行超时熔断/// </summary>/// <typeparam name="T">返参类型</typeparam>/// <param name="action">同步方法</param>/// <param name="timeSpan">等待时长</param>/// <param name="defaultValue">默认值</param>/// <returns></returns>public static T Excute<T>(Func<T> action, TimeSpan timeSpan, T defaultValue = default){var cts = new CancellationTokenSource();var task = Task.Run(action, cts.Token);if (task.Wait(timeSpan)){return task.Result;}else{cts.Cancel();System.Diagnostics.Debug.WriteLine($"{DateTime.Now} 同步方法【{action.Method.Name}】执行超时!");return defaultValue;}}/// <summary>/// 异步执行超时熔断/// </summary>/// <typeparam name="T">返参类型</typeparam>/// <param name="action">异步方法</param>/// <param name="timeSpan">等待时长</param>/// <param name="defaultValue">默认值</param>/// <returns></returns>public static async Task<T> ExcuteAsync<T>(Func<Task<T>> action, TimeSpan timeSpan, T defaultValue = default){var cts = new CancellationTokenSource();var task = action();var delayTask = Task.Delay(timeSpan, cts.Token);var completeTask = await Task.WhenAny(task, delayTask);if (completeTask == task){cts.Cancel(); // 取消延迟任务return await task;}else{cts.Cancel(); // 取消原始任务System.Diagnostics.Debug.WriteLine($"{DateTime.Now} 异步方法【{action.Method.Name}】执行超时!");return defaultValue;}}}
}

调用示例

public async Task<string> Test(int num)
{TimeSpan ts1 = TimeSpan.FromSeconds(num);string result = OverTimeHandler.Excute(Sleep, ts1, $"{DateTime.Now} Sleep OverTime!!!");result += await OverTimeHandler.ExcuteAsync(SleepAsync, ts1, $"{DateTime.Now} SleepAsync OverTime!!!");return result;
}
private string Sleep()
{Thread.Sleep(TimeSpan.FromSeconds(3));System.Diagnostics.Debug.WriteLine($"{DateTime.Now} Sleep finished!");return "Sleep finished!";
}
private async Task<string> SleepAsync()
{await Task.Delay(TimeSpan.FromSeconds(5));System.Diagnostics.Debug.WriteLine($"{DateTime.Now} SleepAsync finished!");return "SleepAsync finished!";
}

结果:

Test方法入参:2

返参:2025/7/24 16:50:23 Sleep OverTime!!!2025/7/24 16:50:25 SleepAsync OverTime!!!

日志:

2025/7/24 16:50:25 同步方法【Sleep】执行超时!
2025/7/24 16:50:26 Sleep finished!
2025/7/24 16:50:27 异步方法【SleepAsync】执行超时!
2025/7/24 16:50:30 SleepAsync finished!

 Test方法入参:4

返参:Sleep finished!2025/7/24 16:52:47 SleepAsync OverTime!!!

日志:

2025/7/24 16:52:47 Sleep finished!
2025/7/24 16:52:51 异步方法【SleepAsync】执行超时!
2025/7/24 16:52:52 SleepAsync finished!

 Test方法入参:6

返参:Sleep finished!SleepAsync finished!

日志:

2025/7/24 16:54:18 Sleep finished!
2025/7/24 16:54:23 SleepAsync finished!

http://www.dtcms.com/a/295829.html

相关文章:

  • [Python] -进阶理解5- Python 模块与包的导入机制解析
  • uniapp中mp-html使用方法
  • 特定日志输出aop实现
  • day62-可观测性建设-全链路监控zabbix+grafana
  • Redis的事务和Lua之间的区别
  • day13 flash
  • 「iOS」黑魔法——方法交换
  • 告别束缚:这款“隐形心电监测仪”让心脏健康管理更自由
  • JavaSE:开发环境的搭建(Eclipse)
  • 企业级数据分析创新实战:基于表格交互与智能分析的双引擎架构
  • 从0到1学习c++ 命名空间
  • 《 java 随想录》| 数组
  • MySQL的命令行客户端
  • 探索双链表:C语言中的链式结构魔法
  • 光谱仪杂散光性能分析
  • 大疆无人机炸机后视频损坏的完美修复案例解析
  • uni-file-picker vue3二次封装(本地上传 + v-model)
  • Mysql命令show processlist
  • Linux基础服务(autofs和Samba)
  • 论文阅读:《针对多目标优化和应用的 NSGA-II 综述》一些关于优化算法的简介
  • OpenCV —— color_matrix_numpy_mat_reshape
  • 新mac电脑软件安装指南(前端开发用)
  • 解决http的web服务中与https服务交互的问题
  • 平时遇到的错误码及场景?404?400?502?都是什么场景下什么含义,该怎么做 ?
  • AI实践:Pydantic
  • 大模型Prompt优化工程
  • pdf文件的属性值怎么修改?修改PDF内部的属性创建时间和修改时间
  • Lua(垃圾回收)
  • omofun官网网站入口,动漫在线看|官方下载
  • AI服务器给一体成型电感带来多大的市场空间