2017-01-19 10 views
-2
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;} 
    } 


} 

この例では、ループ内で関数RunItを実行しています。 RunItはプロセスを非同期で開始し、終了時に匿名ハンドラを割り当てます。同じ関数には、匿名のラムダによって捕捉されるコンテキスト変数があります。私の質問は簡単です - キャプチャされたコンテキストは常に結果と一致すると思いますか?ここでの懸念は、私が成功したことを意味する10回実行していることです.Handlerは、順不同で10回呼び出されます。各コンテキストごとに別々のバージョンの匿名関数がありますか?ループ内のローカル変数のクロージャとキャプチャ

短いストーリー - context.Idは、常に匿名機能でsuccessHandler "id"と一致しますか?

+0

いいえ、もちろんそうではありません。なぜあなたはそれを期待していますか? successHandlerパラメータとはまったく関係のない新しいGuidを明示的に返します。なぜあなたはそれが一致すると思いますか? –

+0

@DavidLこのGUIDを返してコンテキストに割り当て、後で同じGUIDを使用してsuccessHandlerを呼び出すため、非同期的にそれが一致します。 – MistyK

+0

それはあなたの質問で明らかです。それはすべての欠けている文脈です。この質問はそのまま返答することはできません。 –

答えて

0

私はこの質問がdownvotedされた知っていますが、とにかくそれに答えるでしょう。答えは「はい」です。Context変数は繰り返しごとに個別にキャプチャされます。

関連する問題