기본 스레드 동기화를 위해 Waithandle을 처분하십시오
-
21-12-2019 - |
문제
문서에 따르면, .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();
.