2016-10-27 1 views
2
내가 콜백 및 루프에 대한 약간의 문제가 있어요

는 는이 코드 주석에 기록 된대로콜백에서 참조로 전달 된 C# 정수? 나는 10 개 요소가있는 경우

public void DoSth(Action<QueryTextureResult> result, IEnumerable<string> arr) 
{ 
    int totalData = 0; 
    foreach (var element in arr) // let's say arr.Count() is 10 
    { 
     Action<Texture> onImageReceived = (texture) => 
     { 
      if (result != null) 
      { 
       var res = new QueryTextureResult() 
       { 
        Texture = texture, 
        QueryId = queryId, 
        Index = totalData // why this one is always 10 if the callback takes time? 
       }; 

       result(res); 

       Debug.Log("INdex: " + res.Index); 
      } 
     }; 

     imageManager.GetImage("http://image.url", onImageReceived); 

     totalData++; 
    } 

} 

가 있다고 가정은, 그것은, result가 호출 될 시간이 걸린다 왜 내가받은 QueryTextureResult.Index은 항상 10일까요? 그것은 참조로 전달됩니까? 이 문제를 해결할 방법이 있습니까?

+0

변수가 모두 저장되어있어 동일한 메모리 주소를 공유합니다. –

답변

1

코드 예제에서 totalData이 캡처되므로 모든 대리인이 동일한 변수를 참조합니다. 루프가 끝나면 totalData10의 값을 가지며 모든 대표는 동일한 totalData을 읽고 결과적으로 10을 얻습니다.

해결책은 대리인에게 전달하기 전에 변수 복사본을 가져 오는 것이므로 모든 대리인은 자신의 복사본이 있습니다.

foreach (var element in arr) // let's say arr.Count() is 10 
{ 
    var copy = totalData; 
    Action<Texture> onImageReceived = (texture) => 
    { 
     if (result != null) 
     { 
      var res = new QueryTextureResult() 
      { 
       Texture = texture, 
       QueryId = queryId, 
       Index = copy // <== 
      }; 
1

totalData이 closured하고 onImageReceived가 비동기 적으로 호출되기 때문에 그것은 발생합니다. totalData

  • GetImage를 출력 항목 1, 선언

    1. onImageReceived 항목 1
    2. totalData = 1
    3. 위해 호출됩니다

      당신이 3 개 항목을 가지고, 그것은 다음과 같은 순서로 실행할 수 있습니다 가정 항목 2에 대해 onImageReceived이 출력되고, 출력은 totalData

    4. ,를 출력하는 onImageReceived 이벤트를 호출하는, 2
    5. totalData = 2
    6. onImageReceived이 항목 1
    7. totalData = 3
    8. 항목 3이라고 totalData
    9. GetImage를 출력 항목 3, 선언 항목에 대한 완료된라고 totalData ... 지금은 3입니다
    10. onImageReceived 이벤트를 호출하는 항목 2가 완료되었으며 totalData도 3입니다.
    11. 동일 항목 3에 대한 내용은
  • +0

    답변 주셔서 감사합니다. 그래서'index = totalData'는'onImageReceived'가 호출 된 후에 만 ​​채워집니다. – andiwin

    +0

    @andiwinata 예. 'DoSth' 메소드의 시작 부분과'onImageReceived' 액션의 시작 부분에서 두 개의 중단 점을 설정할 수 있습니다. –