2012-04-16 5 views
15

시나리오 : 루프에서 비동기 작업이 프로그램으로 변경 인수를 포함하는 방법을 계속 실행 : 목록이 변수의 현재 값을 추가 할 것입니다, 루프가 빨리 완료하는 작업에 비해 실행값을 변경하여 인수를 태스크 - 동작으로 전달 하시겠습니까?

while(this._variable < 100) 
{ 
    this._variable++; 
    var aTask = Task.Factory.StartNew(() => 
    { 
     aList.add(this._variable); 
     update(this._savePoint); 
    }); 
} 

경우 또는 로컬에 저장된 변수이며 원래 값이 추가 되었습니까?

+3

Jon Skeet이 확인하십시오 : http://csharpindepth.com/Articles/Chapter5/Closures.aspx –

+0

+1 훌륭한 질문! – nawfal

답변

11

클로저는 값이 아닌 변수를 닫습니다. 따라서 _variable을 증가 시키면이이를 참조하는 작업의 동작을 변경할 수 있습니다.

당신은 로컬 복사본을 만들어이 문제를 방지 할 수 있습니다

while (this._variable < 100) 
{ 
    this._variable++; 
    int local = _variable; 
    var aTask = Task.Factory.StartNew(() => 
    { 
     aList.add(local); 
     update(this._savePoint); 
    }); 
} 

또는 상태로 작업에 값을 전달할 수 :

while (this._variable < 100) 
{ 
    this._variable++; 
    var aTask = Task.Factory.StartNew(object state => 
    { 
     aList.add((int)state); 
     update(this._savePoint); 
    }, this._variable); 
} 

_variable의 값을 복사하여이 작업을 모두 새로운 임시 변수. 첫 번째 경우에는 local 변수가 루프 범위 내에 정의되어 있으므로 반복 할 때마다 새로운 변수가 생깁니다. 두 번째 경우에서는 값을 state 인수로 작업에 전달할 때 복사본을 만듭니다. _variable이 참조 유형 인 경우 이러한 솔루션이 작동하지 않습니다. 클론을 수행해야합니다.

+0

변수가 클래스의 인스턴스이면 어떻게됩니까? 'SomeClass localVariable = this._variable'을 루프 내에서 사용하십시오. 참조 인 경우 변경된 상태를받지 못하게하는 방법은 무엇입니까? – asunrey

+1

@Moyler : 루프 내부에서 인스턴스를 복제해야합니다. 즉, 새 인스턴스를 만들고 해당 속성의 값을 원래 인스턴스의 값과 동일하게 만듭니다. –

+0

감사합니다. 확인이 필요했습니다. 또한 원래 예제에는 참조 유형이 필요했습니다. 그래도 한 거래에 2를 얻으려면 좋습니다. – asunrey

관련 문제