在WCF服务中,我将多个请求分派给其他API /库,我不想等待这些任务完成,所以我最终使用Task.Run来完成异步任务而无需等待完成
代码如下所示:
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
});
});
}
我的三个问题是:
setTimeout()
,我需要使用某种 context-copy 技巧来保持调用时variableOne
的当前值,因此当&#34;任务&#34;时,它不会被设置为分配给variableOne
的最新值。 (正在执行JS的功能)正在执行中。
我们是否需要使用C#进行这种复制,还是内置上下文复制? .Net是否评估正在使用的变量,并在调用时创建它们的副本?答案 0 :(得分:2)
List<T>
不是一次性的,所以不,它不能处理。如果您的意思是收集了垃圾,那么如果您可以通过托管代码访问它们,则不会收集任何对象;在处理unsafe
代码时,这只是偶然的事情。
它具有当前时间点变量的值,而不是变量关闭时的值。闭包关闭变量,而不是值。
这里的行为是一样的;闭包关闭变量,而不是值。这就是您需要在lambda中创建variableOne
而不是使用i
的原因。如果您关闭i
,则会获得i
的当前值,但是当您在循环中获取该值的副本时,从不改变该变量(variableOne
),当你关闭它时,变量的值总是与调用委托时变量的值相同。
您当然可以使用以下代码对此进行简单测试:
int i = 3;
Func<int> f = () => i;
i = 42;
Console.WriteLine(f());
如果它打印3
,则表示闭包关闭值。如果它打印42
,那么它会告诉您闭包关闭变量。
答案 1 :(得分:1)
WCF允许您创建one-way services,其中客户端不会等待响应,因此它不会超时。
简而言之,您将方法的IsOneWay属性的OperationalContract属性设置为true
。文档中的以下代码段演示了这一点:
[ServiceContract]
public class OneAndTwoWay
{
// The client waits until a response message appears.
[OperationContract]
public int MethodOne (int x, out int y)
{
y = 34;
return 0;
}
// The client waits until an empty response message appears.
[OperationContract]
public void MethodTwo (int x)
{
return;
}
// The client returns as soon as an outbound message
// is queued for dispatch to the service; no response
// message is generated or sent.
[OperationContract(IsOneWay=true)]
public void MethodThree (int x)
{
return;
}
}