문제

문서에 따르면, .NET의 Waithandle은 명시 적으로 / 암시 적으로 배치되어야합니다.그러나 다음 기본 동기화 작업을 위해이 작업을 수행하는 데 문제가 있습니다.

  • 스레드에서 시간 소모 작업이 실행되고 있습니다.
  • 주 스레드는 사전 정의 된 기간 동안 작업을 완료 할 때까지 대기합니다.주 스레드가 진행해야합니다.작업이 완료되거나 b.시간 초과가 발생했습니다.

여기서 AutoresetEvent 객체를 사용하여 내 시도 :

using(var waitHandle = new AutoResetEvent(false)){
    var worker = new Thread(() =>
    {
        try
        {
            TimeConsumingTask();
            waitHandle.Set(); //throws System.ObjectDisposedException: Safe handle has been closed
        }
        catch (Exception e)
        {...}
    }) {IsBackground = true};
    worker.Start(); //start worker

    const int waitTimeInMs = 5000; 
    var signaled = waitHandle.WaitOne(waitTimeInMs);//block main thread here. 
    if (!signaled)
    { //if timed out
       worker.Interrupt();
    }
}
.

주 스레드가 시간이 나오고 ObjectDisposedException 예외를 일으키는 대기 핸들 객체를 꺼내는 분명한 경쟁 조건이 있습니다.핸들이 올바르게 배치되고 예외를 일으키지 않고이를 설정하는 다른 방법이 있습니까?

도움이 되었습니까?

해결책

확실히,이를 수행하는 데 괜찮은 방법이 없습니다. 본질적으로 야생을 달리고있는 스레드를 떠나는 것에 의해 그 구석에 자신을 그린 것으로 나타났습니다.

그러나 당신은 훨씬 작은 문제에 집중하고 있습니다. 스레드 클래스 자체는 이미 자원 돼지로서 VM의 메가 바이트 및 5 개의 동기화 개체를 소비합니다. 그러나 폐기 () 방법은 없습니다. 이것은 용감한 디자인이었습니다.이 방법을 호출하는 데 괜찮은 방법이 없습니다.

폐기는 옵션 입니다. 그럼에도 불구하고 극적인 일이 발생하지 않습니다. 클래스가 등을 가지고 있으며, 원시 운영 체제 자원이 릴리스되도록하는 것은 Finalizer가 있습니다. 어떤 실행, 결국 원하는만큼 빠르지 않아도됩니다.

이 문제를 덜 용감한 디자인으로 클래스와 비교하십시오. 작업 클래스에는 dispose () 메소드가 있습니다. 나사와 마찬가지로 거의 전화하기가 어렵습니다. .NET Gurus의 안내 는 다음과 같습니다. 그냥 귀찮게하지 마라.

여기에 동일합니다.

다른 팁

사용 범위를 사용하면 새로운 스레드가 즉시 새 스레드를 호출하여 WaithAndle이 폐기되기 때문에 폐기됩니다.

사용 설명서 대신 작업을 완료 한 후에도 명시 적으로 폐기 할 수 있습니다.

waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
   worker.Interrupt();
}
waitHandle.Dispose();
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top