2012-07-26 5 views
3

내 작업의 작업 대리자 내에서 내 작업 인스턴스 (t)를 아래 코드 바로 사용할 수 없습니다. 나는 다음과 같은 오류가 발생합니다 :작업 대리자 내부의 작업 인스턴스

Use of unassigned local variable 't'

코드 :이 경우는 왜

Task t = null; 
t = Task.Factory.StartNew(() => 
{ 
    MessageBox.Show(t.Id.ToString()); 
}); 

누군가가 설명해 주 시겠어요 : 다음 작업을 수행 할 경우 이제 작동

Task t = Task.Factory.StartNew(() => 
{ 
    MessageBox.Show(t.Id.ToString()); 
}); 

?

답변

4

C# 컴파일러는 Task.Factory.StartNew에 대해 아무것도 모릅니다. 컴파일러에 관한 한 t에 대한 액세스는 t이 할당되기 전의 시간을 포함하여 StartNew을 호출 한 후 언제든지 발생할 수 있습니다.

두 번째 코드 단편에는 경쟁 조건이 있습니다. 할당이 완료되기 전에 동시 스레드의 작업이 메시지 상자를 표시하기 시작하면 null 참조 예외가 표시됩니다.

이 실험을 시도

private static Task Wrapper(Action f) { 
    var res = Task.Factory.StartNew(f); 
    Thread.Sleep(1000); 
    return res; 
} 

이제 두 번째 조각에서 Wrapper의 호출로 Task.Factory.StartNew의 직접 전화를 교체하고 프로그램 충돌을보세요.

Task t = null; 
t = Wrapper(() => { 
    MessageBox.Show(t.Id.ToString()); 
}); 
+0

문제의 두 스 니펫은 동일한 경쟁 조건을 갖습니다. 그러나 컴파일러는 모르는 정적 분석에서 오류입니다. –

+0

@HenkHolterman 예, 아직 있습니다. 아이디어는 경쟁 조건을 더욱 분명하게 만드는 것이 었습니다. – dasblinkenlight

+0

위대한 설명, 고마워요. 그렇다면 위임자의 내 작업 인스턴스에 안전하게 액세스 할 수 있습니까? – davenewza

2

먼저 태스크 유형의 오브젝트에 대한 참조를 가져올 수 있도록 t에 값을 지정해야합니다.

첫 번째 코드에서는 값을 t에 할당하고 하나의 명령문에서 사용합니다 (단 하나의 세미콜론 만 사용).

두 번째 예에서는 두 개의 별도 명령문이 있으므로 작동합니다.