2015-01-10 3 views
3

ASP.NET MVC 응용 프로그램을 개발하는 동안 CultureAwaiter이 나타나는데이 인스턴스는 확장 메서드 WithCurrentCulture을 호출 할 때 반환됩니다.ASP.NET ID CultureAwaiter 코드

저는 Microsoft의 비동기 모델에 비교적 신선합니다. 그래서 아래에 표시된 코드의 네 줄 뒤에있는 직관을 이해하는 데 어려움을 겪고 있습니다. ILSpy를 사용하여 어셈블리 파일 버전 "2.1.30612.0"에서 가져 왔음에 유의하십시오 ... MS가 소스를 아직 보지 못하게했다고 생각하지 않습니다.

동일한 스레드에서 동 기적으로 실행한다고 가정하는 해당 네 줄에서 변수 currentCulture이 현재 스레드 문화에 설정되어있는 것 같습니다 (지금까지는 그렇게 좋았습니다). 그러나 나중에 두 줄을 입력하면 변수가 사용되며 현재 스레드의 culture가 할당됩니다 (할당을 되돌릴 수 있음). 그게 무슨 용도예요?

반면 UI 문화는이 네 줄에서 약간 다른 동작을합니다. 변수 이름에서 'UI'/ 'Ui'의 경우를 주목하십시오. 이 네 줄 중 두 번째 줄에서 변수 currentUICulture이 현재 스레드의 UI culture로 설정됩니다 (나중에 사용하기 위해 "기억"하는 것으로 추정 됨). 두 줄 뒤에 현재 스레드의 UI culture가 다른 변수 currentUiCulture (대소 문자에 유의하십시오) ... 메소드의 시작 부분에 정의됩니다.

비동기 모델에 대한 초보자의 이해를 제쳐두고 나는 적어도 CurrentCulture와 CurrentUICulture가이 메소드에서 동일한 가져 오기/설정 동작을 가질 것으로 예상했습니다. 나는 완전히 틀릴 수도 있지만, 내 "내장"느낌은 그 네 줄에서 잘못된 할당이 일어날지도 모른다는 것을 나에게 말하고있다.

아무도 내 이해를 위해이 점을 밝힐 수 있습니까? 아마 ILSpy와 관련이 있습니까?

// Microsoft.AspNet.Identity.TaskExtensions.CultureAwaiter<T> 
public void UnsafeOnCompleted(Action continuation) 
{ 
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
    CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture; 
    this._task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(delegate 
    { 
     // WHAT'S GOING ON IN THE NEXT FOUR LINES? 
     CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
     CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture; 
     Thread.CurrentThread.CurrentCulture = currentCulture; 
     Thread.CurrentThread.CurrentUICulture = currentUiCulture; 
     try 
     { 
      continuation(); 
     } 
     finally 
     { 
      Thread.CurrentThread.CurrentCulture = currentCulture; 
      Thread.CurrentThread.CurrentUICulture = currentUICulture; 
     } 
    }); 
} 

답변

3

이 목적은 다른 스레드에서 실행될 수 있지만 현재 문화권 설정으로 계속 실행하는 것입니다. 그러나 우리는 그 스레드를 소유하고 있지 않기 때문에 그 스레드의 문화를 지속적으로 수정하고 싶지는 않습니다. 그것은 공유되었습니다. 따라서 종료하기 전에 이전 설정을 복원해야합니다.

아마, 디 컴파일러는 오해의 소지가있는 변수 이름만을 보여줍니다. 리플 렉터가 올바르게 처리합니다.

public void UnsafeOnCompleted(Action continuation) 
{ 
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
    CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture; 
    this._task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(delegate { 
     CultureInfo info1 = Thread.CurrentThread.CurrentCulture; 
     CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture; 
     Thread.CurrentThread.CurrentCulture = currentCulture; 
     Thread.CurrentThread.CurrentUICulture = currentUiCulture; 
     try 
     { 
      continuation(); 
     } 
     finally 
     { 
      Thread.CurrentThread.CurrentCulture = info1; 
      Thread.CurrentThread.CurrentUICulture = currentUICulture; 
     } 
    }); 
} 
+0

대단히 고마워요. 반영자를 지불하는 이유처럼 들린다 :). – sammy34