【发布时间】:2015-05-06 16:31:13
【问题描述】:
在 WCF 服务中,我将多个请求分派到其他 API/库,并且我不想等待这些任务完成,因此我最终使用 Task.Run 来完成异步任务无需等待完成 em>。
代码如下所示:
var someList = new List<int>();
var i = 0;
foreach (var item in group)
{
i++;
var variableOne = i;
Task.Run(async () =>
{
// Does the **variableOne** and variable **i** equals the latest value assigned to it, or the value at the time of calling?**
// Can someList be prematurely garbage collected before the tasks run, because the original function containing all the code shown in the example has completed (since Task.Run is not awaited)?
await OcrUtility.ApiOcrUpload(
new OcrUtility.ApiOcrUploadContract()
{
documentList = item.Documents
});
});
}
我的三个问题是:
- 可以在任务内容运行之前提前处置/收集一些列表(或任务内容引用的任何其他对象)吗?
- 任务中的变量 i 是否等于分配给它的最新值,还是调用时的值?
- 我习惯了 Javascript,而且我知道如果我在 javascript 中使用
setTimeout(),我需要使用某种 context-copy 技巧来保持 @ 的当前值调用时为 987654323@,因此在执行“任务”(JS 情况下的函数)时,它不会被设置为分配给variableOne的最新值。 我们是否需要使用 C# 进行这种复制,或者它是否带有内置的上下文复制? .Net 是否评估正在使用的变量,并在调用时创建它们的副本?
【问题讨论】:
-
I wanted to not wait for these tasks to complete几乎可以肯定是一个设计错误。您应该仔细考虑异常是如何出现的,以及您将如何处理更新的部署。特别是,如果 WCF 由 ASP.NET 托管,这种模式尤其危险。 -
不是真的,如果主要操作成功,我不希望客户有超时。将工作完成到最后是 Web 服务的工作,它必须自己处理它们抛出的异常。我猜你想说的是 IIS 而不是 ASP.Net?
-
@MykaEyl 名称无关紧要,但代码确实很危险。您正在尝试使用即发即弃的任务来模拟长时间运行的作业。每当应用程序池被回收或托管进程终止时,此类后台任务都可能被 IIS 终止。
-
是的,我知道关于 IIS,它与任何其他托管系统一样,但您建议如何应对这种影响?我是不是错了,或者除非管理员或程序强制崩溃或回收,否则 IIS 不会杀死它?
-
是的,你错了。回收不是强制的,它是一种定期启动的可靠性机制。首先,client 为什么要超时?该服务可以根据需要运行。 client 需要调整其超时值或异步等待响应。与网站不同,WCF(或任何 Web 服务)预计会运行长时间的作业。
标签: c# .net parallel-processing task-parallel-library