2016-06-16 4 views
3

this person had과 같은 문제가 있습니다. 그러나 .Net 4.5를 사용하여 질문에 답을 얻었지만 .Net 4.0 만 있습니다..Net 4.0을 사용하여 Lock() 내에서 UI 스레드를 호출하는 방법

그래서 나는 this tutorial에 따라 내 자신의 비동기 세마포어를 생성하고 anwer 게시 한 사람의 추가 의견에 따라 내 코드 구현 :

private void Foo() 
{ 
    try 
    { 
     Semaphore.WaitAsync().ContinueWith(previousTask => 
     { 
      if (Dispatcher.FromThread(Thread.CurrentThread) != null) 
      { 
       Bar(); 
      } 
      else 
      { 
       Application.Current.Dispatcher.Invoke(new Action(() => Bar())); 
      } 
     }); 
    } 
    finally 
    { 
     Semaphore.Release(); 
    } 
} 

이 비록 나를 위해 작동하지 않습니다가, 바 병렬로 호출 .

+0

비동기가 발생하기 전에 세마포어를 해제해야합니다. 이 모든 것 대신에'await'을 사용해야합니다. – SLaks

+0

@SLaks : 나는 닷넷 4.5가 없다. – gartenriese

+1

그런 다음 Microsoft.Bcl.Async를 사용하십시오. – SLaks

답변

4

세마포어를 너무 일찍 공개하고 있습니다. 끝에 ContinueWith 처리기에서 해제하십시오.

Foo()은 실제로 동기화 된 코드와 관계없이 즉시 반환됩니다.

if (Dispatcher.FromThread(Thread.CurrentThread) != null)도 매우 의심 스럽습니다. 마샬링해야하는지 여부는 을 알고 있어야합니다.

연속성이 인라인 될 수 있기 때문에 실제로 실행되는 스레드를 예측하기가 어렵습니다. 이것은 TPL에서 매우 불쾌한 비 결정론입니다. 해당 연속에 대한 UI 작업 스케줄러를 지정해야합니다. 그런 식으로 마샬링 할 필요가 없습니다.

또한 .NET 4.0에서 await을 사용할 수 있으므로이 질문은 유용하지 않을 수 있습니다.