关闭并捕获循环中的局部变量

时间:2017-01-19 21:42:12

标签: c# closures

using System;

public class Program
{
    public static void Main()
    {
        IRunnable runnable = new Runnable();
        for(int i=0;i<10;i++)
        {
            RunIt(runnable);
        }

    }

    public static void RunIt(IRunnable runnable)
    {
        var context = new Context();
        context.Id = runnable.RunAsync((id,result)=>{
            //context.Id will always match "id" here?
            context.Result = result; // can I assume here that this is the same context?
        });
    }


    public interface IRunnable
    {
        int RunAsync(Action<string,string> successHandler);
    }

    public class Runnable : IRunnable
    {
       private Random _random = new Random();

        public string RunAsync(Action<string,string> successHandler)
        {

            var guid = Guid.NewGuid().ToString();
            Task.Run(()=>
             {
               Thread.Sleep(_random.Next(0,1000));
                successHandler(guid, "result")
             });
            return guid;
        }
    }

      public class Context
    {
        public string Id {get;set;}
        public string Result{get;set;}
     }


}

在这个例子中,我在一个循环中运行函数RunItRunIt以异步方式启动进程,并在完成后指定匿名处理程序。在同一个函数中,我们有一个上下文变量,它将由匿名lambda捕获。我的问题很简单 - 我可以假设捕获的上下文总是匹配结果吗?我担心的是我运行了10次,这意味着successHandler将以无序方式被调用10次。每个上下文是否都有单独的匿名函数版本?

长话短说 - context.Id总是会在匿名函数中匹配successHandler“id”吗?

1 个答案:

答案 0 :(得分:0)

我知道这个问题被低估了,但无论如何我都会回答。答案是肯定的,每次迭代都会单独捕获Context变量。