2011-05-13 6 views
17

나는 재미를 System.Threading.Tasks와 함께 일하고있다. 그러나 내가 보는 많은 코드 샘플은 다음과 유사합니다.작업을 처분해야합니까?

Dim lcTask = Task.Factory.StartNew(Sub() DoSomeWork()) 
Dim lcTaskLong = Task.Factory.StartNew(Sub() DoSomeWork(), TaskCreationOptions.LongRunning) 
Task.WaitAll(lcTask, lcTaskLong) 

이는 샘플의 범위입니다.
작업은 IDisposable을 구현하므로 분명히 처리해야합니다.하지만 그냥 "불 또는 잊어 버리려는 경우"어떻게해야합니까?

처리하지 않으면 스레드/핸들/메모리/카르마가 누출됩니까? "잘못된"작업을 사용하고 있습니까? (대리인 만 사용하고 작업을 남겨 두어야합니까?)

ContinueWith()으로 처분 할 수 있습니까? (즉, 러시아 룰렛처럼 보인다.)

답변

18

엄지 손가락의 일반적인 규칙은 항상 모든 IDisposable 구현에 Dispose(), TaskTask<T>가 종종 종료 자이 알아서하는 것이 좋은 일 대소를 호출된다.

작업이 IDisposable을 구현하는 이유는 주로 내부 WaitHandle 때문입니다. 이것은 작업 연속이 올바르게 작동하도록하고 작업에 연속이있을 때만 사용되는 데 필요합니다. 연속이없는 경우 작업의 Dispose 메서드는 실제 효과가 없으므로이 경우 필요하지 않습니다.

대부분의 경우 작업 계속이있는 경우 Dispose()를 제대로 호출 할 수 있도록 코드를 작성하는 것이 매우 어렵습니다. 명령문을 사용하면 태스크 호출이 일반적으로 비동기이기 때문에 일반적으로 태스크 인스턴스에서는 작동하지 않습니다. 작업을 너무 일찍 처리하는 것은 매우 쉽습니다. 특히 using 문을 사용할 때는 더욱 그렇습니다.

작업에 대한 참조를 유지하고 Dispose()를 올바르게 호출하는 것이 비교적 간단하다면 그렇게 할 것입니다. 그러나 이것이 논리가 훨씬 복잡 해지면 일반적으로 Task가 IDisposable이 아닌 것처럼 가장하여 태스크의 종료 자에서 정리할 수 있습니다.

자세한 내용은 reading this thread on the MSDN forums을 권장합니다. 여기서 Stephen Toub은 Task가 IDisposable을 세부적으로 구현하는 이유를 설명하고 위의 제 제안과 유사한 지침을 제공합니다.

+1

및 \t \t [CodeAnalysis.SuppressMessage ("Microsoft.Reliability", "CA2000", Justification = "http://stackoverflow.com/questions/5985973/do-i-need-to-dispose-of -a-task ")] – GarethOwen

+2

당신이 연결하는 Stephen Toub 스레드를 보면,"작업 대기가 제대로 작동 할 수 있도록 대기 핸들이 필요합니다. 작업이 계속되는 경우 작업의 Dispose 메서드는 실제 효과가 없습니다 ... "그러나 Toub에 따르면 Task.Dispose는 잠재적으로 이벤트 핸들을 래핑하는 Task로 인해 존재합니다. 지속을 사용하면 이벤트 핸들이 할당되지 않고 Dispose 값이 크게 감소합니다. " 즉 위에서 암시 한 것과 반대입니다. –

관련 문제