我知道这是一个糟糕的设计,我正在努力寻找任何不这样做的理由,所以我需要一些帮助.

我有一个正在命中的API端点,需要在最多几秒钟内返回OK响应.目前,我们正在进行调用并处理大量数据,然后返回OK,但是,如果DoLotsOfWork方法超时,则不会返回OK响应.

public IActionResult DoWork([FromBody] MyDTO myDto){
     DoLotsOfWork();
    return OK()
}

现在我建议我们迁移到某种类型的队列,让作业(job)在那里运行,但我被拒绝了,因为这项工作将花费很长时间.相反,我被告知要这么做.

public IActionResult DoWork([FromBody] MyDTO myDto){
   try{
       return OK();
   }
   catch{
   }
   finally{
      DoLotsOfWork();
   }  
}

有人知道这样做有什么缺点吗?

推荐答案

因为实际的问题看起来完全是"有什么缺点?",而且您似乎知道try-catch-finally是如何工作的,作为一种在API响应后执行代码的方式(尽管在 comments 和答案中有些人解释了它的作用),我只会链接到Stephen Cleary编写的this very well-written StackOverflow answer to a similar question.

Edit 2: vatbub's answer below用这种方法列出的问题在#4中提出了一个很好的观点(1-3基本上重申了try-catch个误用),下面的描述详细说明.

Edit:以防它从互联网上消失:

我需要"开火然后忘却"

我有一篇博客文章,详细介绍了几种不同的 接近fire-and-forget on ASP.NET美元.

总而言之:首先,试着根本不做一劳永逸的事情.就快到了 一直都是个坏主意.你真的想"忘记"吗?就像在,不关心 它是否成功地完成了?是否忽略任何错误?接受 偶尔在没有任何日志(log)通知的情况下"丢失工作"?几乎总是, 答案是否定的,"一发不可收拾"不是合适的方法.

可靠的解决方案是构建适当的分布式体系 struct . 也就是说,构造一个表示要完成的工作的消息,并 将该消息排队到可靠队列(例如,Azure队列、MSMQ等). 然后具有处理该队列的独立后端(例如,Azure 网络作业(job)、Win32服务等).

我应该只调用Task.Run()而不使用任何task-await吗?

不是的.这可能是最糟糕的解决方案.如果你必须这样做 然后忘记,你不愿意构建一个分布式的 建筑,然后考虑Hangfire.如果这对你不起作用, 那么至少你应该登记你的牛仔背景工作 使用ASP.NET运行时(通过 HostingEnvironment.QueueBackgroundWorkItem或者我的ASP.NET Background Tasks library.请注意,QBWI和AspNetBackEarth Tasks都是 不可靠的解决方案;它们只会将您失败的可能性降至最低 工作,而不是阻止它.

Csharp相关问答推荐

LINQ无法翻译SQLFunctions方法

如何阻止注释被包含在C#release build. exe中

如何在C#中将对象[*,*]直接转换为字符串[*,*]?

C#方法从AJAX调用接收NULL

使用Orleans进行的单元测试找不到接口的实现

MigraDoc文档

由于POST中的应用程序/JWT,出现不支持的内容类型异常

异步实体框架核心查询引发InvalidOperation异常

依赖项注入、工厂方法和处置困境

LINQ to Entities中的加权平均值

在try 使用访问服务器上的文件夹时,如何解决CORS错误.NET核心API

关于扩展文件类C#的矛盾

对于PowerShell中的ConvertTo-SecureString方法,Microsoft如何将初始化向量添加到AES加密中的安全字符串?

异步任务调用程序集

.NET8Blazor-为什么Rapzor渲染在for循环之后显示?

如何在单击按钮后多次异步更新标签

如何在ASP.NET Core 8中获取键控服务词典

如何在JSON:API中定义的&过滤查询参数系列&标准的GET请求中传递多个相关参数?

为什么我不能在固定语句中使用外部函数?

MS Project读取项目自定义域