繁体   English   中英

使用Task.Run异步任务和数据收集,无需等待

[英]Async tasks and data collections using Task.Run without waiting

在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
              });
      });
}

我的三个问题是:

  1. 可以在运行任务内容之前过早处置/收集someList(或Task内容引用的任何其他对象)吗?
  2. 任务中的变量i等于分配给它的最新值,还是调用时的值?
  3. 我已经习惯了Javascript,而且我知道,如果我确实在javascript中使用setTimeout() ,则需要使用某种上下文复制技巧,以便在调用时保持variableOne的当前值,因此它不会在执行“任务”(对于JS为函数)时,将其设置为分配给variableOne的最新值。 我们是否需要使用C#进行这种复制,或者它是否内置了上下文复制? .Net是否评估正在使用的变量,并在调用时创建它们的副本?
  1. List<T>不是一次性的,所以不能,它不能被处置。 如果您的意思是收集垃圾,那么如果您可以通过托管代码访问对象,则将不会收集任何对象。 在处理unsafe代码时,这甚至是什至没有的事情。

  2. 它具有当前时间点的变量值,而不是关闭变量时的值。 闭包关闭变量而不是

  3. 这里的行为是相同的。 闭包关闭变量,而不是值。 这就是为什么您需要创建variableOne而不是在lambda中使用i的原因。 如果你关闭了i你会得到的当前值i ,但是当你正在做的是值的副本循环,永不变异变量( variableOne ),该变量的值,当你关闭了它是调用委托时,该值始终与变量的值相同。

您当然可以使用以下代码对此进行简单测试:

int i = 3;
Func<int> f = () => i;
i = 42;
Console.WriteLine(f());

如果输出3 ,则表示闭包关闭了 如果它显示42则表示关闭了变量

WCF允许您创建单向服务 ,客户端不会等待响应,因此它不会超时。

简而言之,您可以将方法的OperationalContract属性的IsOneWay属性设置为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;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM