【发布时间】:2018-09-12 19:16:55
【问题描述】:
我已经在Task.Run 中封装了这个动作,但似乎我遗漏了一些非常基本的东西。但是想不通。
public void SaveOrderList(List<Order> inputList)
{
Dictionary<string, string> result = new Dictionary<string, string>();
string code = string.Empty;
Task.Run(() =>
{
foreach (var item in inputList)
{
code = CreateSingleOrder(item);
result.Add(item.TicketNumber, code);
}
////TODO: Write logic to send mail
emailSender.SendEmail("abc@xyz.com");
});
}
由于inputList 中可能有许多条目,并且每个条目可能需要 5 秒的时间来处理,所以我不希望最终用户阻止 UI。相反,我会发送一封邮件并通知有多少处理成功,哪些处理失败。
要实现这一点,我最清楚的是Task.Run。但是,问题是一旦函数完成,我看不到 foreach 循环中的代码曾经工作过,因为它从来没有进入数据库。
谁能帮我找出我在这里缺少什么。
仅供参考,此函数是从 Web API 调用的,而 Web API POST 方法是从 javascript 调用的。下面是 Web API 端点的代码。
[HttpPost, Route("SaveOrderList")]
[ResponseType(typeof(bool))]
public IHttpActionResult SaveOrderList(List<Order> orderList)
{
orderManagerService.SaveOrderList(orderList)
return this.Ok();
}
提前感谢您的帮助。
【问题讨论】:
-
第一个建议是运行带有调试器的程序,在 foreach 循环中的行上放置一个断点,看看会发生什么。如果您的调试器在整个 lambda 表达式而不是单个行上放置断点,则将 foreach 循环移至其自己的方法中,这不会成为问题
-
您不应该在 Web 上实现运行后忘记代码。没有人会保证在响应发送给客户端后进程不会被杀死。
-
@LordWilmore 当我将调试器放入 foreach 循环中时,一切正常。列表中的所有条目一一执行,然后 emailSender 被正确调用。当我删除应用程序中的所有断点时,似乎没有任何效果。
-
@hardkoded 有没有办法处理 UI 不应因长时间任务而被阻塞的情况?我想我可以在 task.run 中放一个 try catch,这样如果有任何错误,我会阅读字典并找出在引发此异常之前执行了多少次。
-
好吧,你正在创建一个即发即弃的任务,它不应该等到任务完成。当您完全不知道代码是否正确传递时,您也会返回 200 OK
标签: c# asp.net-web-api async-await task-parallel-library