2012-05-24 40 views
10

Uygulamam donduktan sonra, bir hata nedeniyle, TimeSpan numaralı hesaplanmış olan bir hesaplanmış TimeSpan sağladığı Task.Delay() (veya .NET 4.0'da TaskEx.Delay()) tarafından oluşturulan bir görevde bekleyen bir iş parçacığının nedenini izledim. TotalMilliseconds'dan -1'a eşit veya daha az ve -2'dan daha büyük (yani, -10000 ila -19999 arası keneler dahil olmak üzere).Task.Delay() neden sonsuz bir gecikmeye izin veriyor?

O ayarlayarak (eğer -2 milisaniye veya daha düşük olan bir negatif TimeSpan geçerken, yöntemi doğru bir ArgumentOutOfRangeException atar, ancak yukarıda açıklanan aralığından olumsuz TimeSpan sağlamak, bunun tamamlar asla bir Task döndürdüğünü görünür altta yatan System.Threading.Timer, sonsuza işaret eden bir dueTime-l'e karşılık gelir). Bu, o görevde ayarlanan tüm ilerlemelerin hiçbir zaman yürütülmeyeceği anlamına gelir ve Task üzerinde .Wait() olan herhangi bir zayıf iş parçacığı sonsuza dek engellenir.

Hiçbir zaman tamamlanmayan, Task nu doldurabilir? Böyle bir geri dönüş değeri beklenir mi? Bu özel aralıktaki değerler de dahil olmak üzere .Delay()'a herhangi bir negatif değer geçmemeli, ArgumentOutOfRangeException? Eksiksiz bir süreyi tamamlamak için süresiz olarak beklemek istediğiniz süreyi beklemek istediğinizde, ancak sonunda tamamlanacaksa,

+1

MSDN dokümanı, -1'e izin verme konusunda oldukça açık, bu yüzden doğru davranıyor gibi görünüyor. Bu aşırı yüklenme için kullanım durumundan emin değilsiniz, ancak bir iptal belirteci alan aşırı yüklenmeyle 'adil' iptali için beklemenin bir yolu olabilir. –

+0

@James: -1'e izin vermede açık değil, -1'den küçük değerlere izin vermiyor. "System.Threading.Timer" belgelerinin aksine -1 'i geçerseniz ne olacağını söyleyemez. Neredeyse belgelenen özel durum listesi kaynak kodundan otomatik olarak oluşturulmuş gibi görünüyor. Ve eğer 'adil' iptal için bekliyoruz, neden bile 'Task.Delay()' için bir çağrı yapmak? –

+0

Bozuk olduğunu düşünüyorsanız, bağlantıda bir hata yapın. -1'in altında olduğunu belirten bir doküman, -1'in geçerli olduğunu söyleyerek açık (bana). Eğer amaç -1 değeri geçersiz ise "0'dan düşük geçersiz" yazmak daha kolay olurdu. Doc ve kod her ikisi de -1 izin verdiğinden, bu Tasarım By olduğunu düşünüyorum, ama bağlanmak için çekinmeyin bir hata (daha rastgele bir SO iplik daha BCL ekibi tarafından işlenmesi olasılığı, sanırım) –

cevap

7

Timeout.Infinite veya -1 yararlıdır.

Win32 API ayrıca, sonsuz zaman aşımları için sabit bir INFINITE = -1 kullanır.

Normalde UI iş parçacığını dondurabildiği için (bu sizin sorununuza benziyor) bir UI dizesinde kullanmak istemezsiniz. Ancak, çalışan iş parçacığında geçerli kullanım durumları vardır - ör. Bir istemciden bağlantı beklerken engelleyen bir sunucu.

+0

Sonsuz bir zaman aşımı yararlıdır. Sonsuz bir gecikme değildir (bu nedenle ilk paragraf geçerli değildir). Dünyada sonsuza dek ne geciktirmek isterdin? Sen de yapamazsın. '-1' uygulama detayının 'System.Threading.Timer' (veya Win32 timer) 'den' Task.Delay() 'yöntemine kadar yayılacağı bana hiç bir anlam ifade etmiyor.Microsoft'un, farkında olmadığım bazı kullanım durumları olmadıkça, geliştiricilerin "başarı çukuruna" itme tasarım prensibine aykırıdır. –

+0

Ayrıca, bir UI iş parçacığı kullanmıyorum. Durdurulması istendiğinde, bir [TAP] (http://www.microsoft.com/en-us/download/details.aspx?id=19957) temelli yöntemini çağırarak bir kapatma yordamı gerçekleştirmesi gereken bir Windows Hizmeti'dir. Çalıştırmak için çok uzun sürebilir, bu yüzden zorla kapatma işlemini gerçekleştirecek bir gecikme görevi de oluşturur. Daha sonra her iki görevde bir '.WaitAny()' yapar ve orijinal görev son derece uzun bir zaman aldığından ve gecikme görevi hiçbir zaman tamamlanmayacağından (bir istisna atmak yerine) hizmetin askıda kaldığı görüldü. –

+1

İstemciden bağlantı beklemeyi engelleyen bir sunucu, hiçbir zaman tamamlamayan bir Görev kullanır? Bir örnek gösterebilir misin? –

2

Bir Task.WhenAny() bloğundaki kodun doğru olarak beklediğim görevlerden birini ele aldığından emin olmak istediğim alay senaryolarında, diğer görevleri alayım ve Görev'i sağlamak için sonsuz bir gecikme kullanabilirim .Ne zaman bir sonsuz gecikme olarak alamadım görevini işliyor.

+2

İlginç kullanım-case, ben yeni TaskCompletionSource(). Task 'hiç bitmeyen bir görev sunmak için daha açık ve net olacağını düşünüyorum rağmen. –

İlgili konular