2010-05-28 2 views
4

몇 초 동안 완료해야하는 몇 가지 작업을 동 기적으로 수행하는 방법이 필요하지만 몇 분 정도 걸릴 수 있습니다. 시간이 지나면 결과에 신경 쓰지 않습니다. 여기에 내가 컴파일러가 생성 delegate.BeginInvoke 사용하여 지금 그것을하고있어입니다 :동기 동작에 대한 더 나은 시간 초과 감지

static void Main() 
{ 
    bool disposed = false; 
    var wait = new ManualResetEvent(false); 
    var a = new Action(
     () => 
      { 
       Thread.Sleep(1000); // <- some looong action 

       if (!disposed) 
        lock (wait) 
         if (!disposed) 
          wait.Set(); 
      }); 

    a.BeginInvoke(a.EndInvoke, null); 

    bool success = wait.WaitOne(500); 
    Console.WriteLine(success ? "success" : "timeout"); 

    lock (wait) 
    { 
     wait.Dispose(); 
     disposed = true; 
    } 

    Console.ReadLine(); 
} 

추한 보인다. 그리고 나는 람다 클로저의 disposed 변수가 수정되었다는 것을 알고 있습니다. (ReSharper와는 달리이 C# 기능을 좋아합니다). 내가 처분하고 싶기 때문에 모두 ManualResetEvent. .NET4에서 더 나은 접근 방식을 제안 할 수 있습니까? 아마도 이벤트를 처리하지 않고 GC에 의존해야합니까?

주 : ManualResetEvent.Set()은 처분 된 인스턴스에서 수행하려고하면 폭발합니다.

+0

BeginInvoke 호출은 동기식이 아닌 비동기식 작업을 시작하는 방법입니다. – Task

+0

맞긴하지만 타임 아웃 간격 내에서 동 기적으로 완료하고 싶습니다. – repka

답변

2

윽, 지금 내가 사용하는 코드 샘플에서 좀 더보고 있음을 컴파일러가 생성 나는 내 목표를 위해 정확히 AsyncWaitHandle을 가지고 IAsyncResult 반환 참조 delegate.BeginInvoke을 : AsyncResult의 사건에 핸들을 기다려야

var a = new Action(() => Thread.Sleep(1000)); // <- some looong action 
IAsyncResult asyncResult = a.BeginInvoke(a.EndInvoke, null); 
bool success = asyncResult.AsyncWaitHandle.WaitOne(500); 

을 사실 ManualResetEvent의 인스턴스는 비동기 호출이 완료 될 때 스레드 풀 스레드에서 자동으로 처리됩니다.

+2

예. 하지만 실제 차이는 없으며 EndInvoke() 만 처리 할 수 ​​있습니다. 대기 시간이 초과되면 전화를 걸 수 없습니다. 귀찮게하지 마십시오. 커널 이벤트는 계속 실행중인 스레드에 비해 싸고 땅콩입니다. –

4

아니요. Dispose 호출을 건너 뛰고 GC를 사용하면 안됩니다. 자원 낭비, 평범하고 단순합니다.

.NET 4.0에서는 System.threading 어셈블리의 새로운 버전 인 Task Parallel Library을 살펴볼 것입니다.

특히 Task classWait method을 확인하면 시간 제한을 지정할 수 있습니다.

또한 시간이 초과 된 경우 cancel a Task 방법을 확인하는 것이 좋습니다.

관련 문제