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()? (러시아 룰렛 경기 같아.)

1 답변


18

정상적인 어림짐작은 항상 전화하는 것이지만Dispose()모두에IDisposable구현,TaskTask<T>종종 파이널 라이저가 이것을 처리하는 것이 더 나은 경우가 하나 있습니다.

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

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

귀하의 경우, 작업에 대한 참조를 유지하고 Dispose ()를 올바르게 호출하는 것이 비교적 간단하다면 그렇게 할 것입니다. 그러나 이것이 당신의 논리를 훨씬 더 복잡하게 만드는 원인이된다면 나는 보통 Task가 그렇지 않은 것처럼 가장 할 것입니다.IDisposable작업의 종료 자에서 정리할 수 있습니다.

자세한 내용은MSDN 포럼에서이 글을 읽으십시오.여기서 Stephen Toub은 Task가 IDisposable을 세부적으로 구현하는 이유를 설명하고 위의 제 제안과 유사한 지침을 제공합니다.


  • 그리고 ... [CodeAnalysis.SuppressMessage ( "Microsoft.Reliability", "CA2000", Justification = "stackoverflow.com/questions/5985973/… - GarethOwen
  • 링크 된 Stephen Toub 스레드를 보면, 작업 대기가 제대로 작동하도록하려면 " 대기 핸들 >이 필요하고 작업에 계속이있을 때만 사용한다고하면 역순으로 처리한다고 생각합니다. 연속이없는 경우 작업 배출 방법은 실제 효과가 없습니다. " 그러나 Toub에 따르면, "Task.Dispose는 태스크가 잠재적으로 이벤트 핸들을 래핑하기 때문에 존재한다 ... 당신이하는 모든 작업이 연속을 사용하고 있다면, 그 이벤트 핸들은 결코 할당되지 않고 Dispose의 값은 크게 줄어든다. " 즉 위에서 암시 한 것과 반대입니다. - Daniel Earwicker

연결된 질문


관련된 질문

최근 질문