2012-05-24 6 views
10

내 응용 프로그램이 동결 된 후 Task.Delay() (또는 .NET 4.0의 경우 TaskEx.Delay())으로 생성 된 TimeSpan 컴퓨터에서 발생하는 작업을 기다리는 스레드의 원인을 추적하여 버그로 인해 TimeSpanTotalMilliseconds-1 이하이고 -2보다 큼 (즉, -10000 ~ -19999 틱 범위의 모든 위치).Task.Delay()가 무한 지연을 허용하는 이유는 무엇입니까?

이 설정 (당신이 -2 밀리거나 낮은 음의 TimeSpan 통과 할 때,이 방법은 올바르게 ArgumentOutOfRangeException 발생하지만, 위에 설명 된 범위에서 음의 시간 범위를 제공 할 때,이 완료 결코 Task 반환 나타납니다 밑에있는 System.Threading.TimerdueTime으로 -1은 무한 함을 나타냄). 즉, 해당 작업에 설정된 연속성은 결코 실행되지 않고 에 .Wait()에 발생하는 불량 스레드는 영구적으로 차단됩니다.

완료되지 않은 Task에는 어떤 용도로 사용할 수 있습니까? 누구나 그러한 반환 가치를 기대합니까? 해당 범위의 값을 포함하여 .Delay()에 음수 값이 전달되면 ArgumentOutOfRangeException을 던지시겠습니까?

+1

MSDN 문서는 -1을 사용하는 것에 대해 매우 명시 적이므로 올바르게 작동하는 것으로 보입니다. 해당 오버로드에 대한 유스 케이스는 확실하지 않지만 취소 토큰을 사용하는 오버로드로 인한 '그냥'취소를 기다릴 수있는 방법 일 수 있습니다. –

+0

@James : -1을 허용하는 것이 명시 적이지 않습니다. -1보다 낮은 값을 허용하지 않는 것이 명백합니다. 'System.Threading.Timer'의 문서와 달리, -1을 전달하면 어떤 일이 일어날 지 말조차하지 않습니다. 문서화 된 예외 목록이 소스 코드에서 자동으로 생성 된 것처럼 보입니다. 그리고 '그냥'취소를 기다리고 있다면, 왜'Task.Delay()'를 호출할까요? –

+0

깨진 것 같으면 connect에 버그를 신고하십시오. "-1보다 낮은 것"이라고하는 문서는 -1이 유효하다는 것을 명시 적으로 말합니다. 의도가 -1 인 경우 "0보다 낮다"가 유효하지 않으므로 쓰기가 쉬울 것입니다. 의사와 코드 모두 -1을 허용하기 때문에 이것은 By Design에 의한 것이라고 생각하지만 연결에 버그가 있으면 자유롭게 파일을 보냅니다 (BCL 팀에서 임의의 SO 스레드보다 처리 가능성이 높음) –

답변

7

Timeout.Infinite 또는 -1은 완료하는 데 불확실한 시간이 걸리지 만 결국 완료되는 장기 실행 작업을 무기한 대기하려는 경우에 유용합니다.

또한 Win32 API는 무한 제한 시간에 상수 INFINITE = -1을 사용합니다.

일반적으로 UI 스레드에서 UI를 사용하고 싶지는 않습니다. UI가 문제가 될 수 있습니다. 하지만 작업 스레드에서 유효한 유스 케이스가 있습니다 (예 : 클라이언트와의 연결 대기를 차단하는 서버.

+0

무한 타임 아웃이 유용합니다. 무한한 지연은 없습니다 (따라서 첫 번째 단락은 적용되지 않습니다). 전 세계에서 영원히 지연시키고 자하는 것이 무엇입니까? 당신은 단지 그것을 수행하지 않을 수도 있습니다. 그것은 단지'-1'의 구현 세부 사항이'System.Threading.Timer' (또는 Win32 타이머)에서'Task.Delay()'메소드까지 전파 될 것이라는 것을 이해하지 못합니다.마이크로 소프트가 잘 모르는 유스 케이스가 아니라면, 개발자들을 "성공의 구덩이"에 몰아 넣는 디자인 원칙에 반하는 것이다. –

+0

또한 UI 스레드에서 사용하지 않습니다. 중지 요청시 [TAP] (http://www.microsoft.com/en-us/download/details.aspx?id=19957) 기반 메서드를 호출하여 종료 루틴을 수행해야하는 Windows 서비스입니다. 실행하는 데 너무 오래 걸릴 수 있으므로 강제 종료를 수행하는 지연 작업도 생성됩니다. 그런 다음 두 작업에서'.WaitAny()'를 수행하고 원래 작업이 매우 오랜 시간이 걸리고 지연 작업이 (예외를 던지는 대신) 완료되지 않으므로 서비스가 중단 된 것으로 보입니다. –

+1

클라이언트와의 연결을 기다리는 것을 차단하는 서버는 어떻게 완료되지 않는'Task'를 사용합니까? 예를 보여줄 수 있습니까? –

2

조만간 Task.WhenAny() 블록의 코드가 제대로 기다려온 작업 중 하나를 처리하도록하려는 mocking 시나리오에서 나는 다른 작업을 조롱하고 무한 지연을 사용하여 Task .Any가 무한한 지연으로 조롱하지 않은 작업을 처리하고 있습니다.

+2

흥미로운 유스 케이스이지만, 'new TaskCompletionSource(). Task'를 사용하여 끝이없는 작업을 제공하는 것이 더 명확하고 명확해질 것이라고 생각합니다. –

관련 문제