WebClient.DownloadFileTaskAsync() 真的不会超时吗?
Does WebClient.DownloadFileTaskAsync() never actually timeout?
在异步之前的日子里,人们想知道如何在 WebClient
上设置超时,答案只是扩展基础 class 并覆盖 GetWebRequest()
并设置超时。
protected override WebRequest GetWebRequest(Uri address)
{
// NOTE: this override has no affect if the Async methods are used!!!
WebRequest request = base.GetWebRequest(address);
((HttpWebRequest)request).Timeout = 20 * 60 * 1000;
((HttpWebRequest)request).ReadWriteTimeout = 20 * 60 * 1000;
return request;
}
假设人们需要更长的超时。
然后随着 xyzTaskAsync()
方法的添加,人们想知道如何设置超时,答案是使用由本地计时器驱动的 CancellationToken。
所以我猜假设人们需要请求在给定时间后结束。
所以这是否意味着DownloadFileTaskAsync()
或DownloadStringTaskAsync()
永远不会自己超时?超时故障不是任何网络操作的固有部分吗?
我已经使用 GetWebRequest()
覆盖设置了一个非常小的超时值。调用非异步方法时抛出超时异常,调用异步方法时不会抛出超时异常。
我已经反编译了 System.Net 库,但是异步方法似乎调用了一些不容易被发现的缓存匿名 lambda。
有谁确切知道 DownloadXyzTaskAsync()
方法是否以相当于无限超时值的方式执行?
同步操作正在阻塞,这意味着线程在某种等待句柄上被阻塞。等待可以是无限的(如果操作本身没有结束,那么等待是无限的)或者等待可以收到某种超时,之后它会解除阻塞和超时。
异步操作本质上是异步的,没有任何主动部分在做某事。没有线程被阻塞或类似情况。这意味着它本质上不能在没有任何指示的情况下真正超时或取消,即使这样操作也只是被放弃而不是取消。这通常是 CancellationToken
(超时后可能会或可能不会用计时器发出信号)。
因此,此(以及任何其他类型的)异步操作需要一些东西(即 CancellationToken
)才能超时。该库确实可以在内部使用计时器,但在 .Net 中很少这样做,因为这是意想不到的,您可以通过自我取消 CancellationToken
.
自己做到这一点
因此,在这种特定情况下和一般情况下,异步方法通常不受配置的超时的影响。 Socket
、TcpClient
、UdpClient
等也是如此
现在,如果您想从 HttpWebRequest
的实际代码中确认,您可以看到超时用于创建计时器队列 here. That queue is used to create a timeout timer in GetResponse
but never in BeginGetResponse
。那就是在 DownloadXXXTaskAsync
.
中使用的 DownloadXXXAsync
中使用的异步选项
在异步之前的日子里,人们想知道如何在 WebClient
上设置超时,答案只是扩展基础 class 并覆盖 GetWebRequest()
并设置超时。
protected override WebRequest GetWebRequest(Uri address)
{
// NOTE: this override has no affect if the Async methods are used!!!
WebRequest request = base.GetWebRequest(address);
((HttpWebRequest)request).Timeout = 20 * 60 * 1000;
((HttpWebRequest)request).ReadWriteTimeout = 20 * 60 * 1000;
return request;
}
假设人们需要更长的超时。
然后随着 xyzTaskAsync()
方法的添加,人们想知道如何设置超时,答案是使用由本地计时器驱动的 CancellationToken。
所以我猜假设人们需要请求在给定时间后结束。
所以这是否意味着DownloadFileTaskAsync()
或DownloadStringTaskAsync()
永远不会自己超时?超时故障不是任何网络操作的固有部分吗?
我已经使用 GetWebRequest()
覆盖设置了一个非常小的超时值。调用非异步方法时抛出超时异常,调用异步方法时不会抛出超时异常。
我已经反编译了 System.Net 库,但是异步方法似乎调用了一些不容易被发现的缓存匿名 lambda。
有谁确切知道 DownloadXyzTaskAsync()
方法是否以相当于无限超时值的方式执行?
同步操作正在阻塞,这意味着线程在某种等待句柄上被阻塞。等待可以是无限的(如果操作本身没有结束,那么等待是无限的)或者等待可以收到某种超时,之后它会解除阻塞和超时。
异步操作本质上是异步的,没有任何主动部分在做某事。没有线程被阻塞或类似情况。这意味着它本质上不能在没有任何指示的情况下真正超时或取消,即使这样操作也只是被放弃而不是取消。这通常是 CancellationToken
(超时后可能会或可能不会用计时器发出信号)。
因此,此(以及任何其他类型的)异步操作需要一些东西(即 CancellationToken
)才能超时。该库确实可以在内部使用计时器,但在 .Net 中很少这样做,因为这是意想不到的,您可以通过自我取消 CancellationToken
.
因此,在这种特定情况下和一般情况下,异步方法通常不受配置的超时的影响。 Socket
、TcpClient
、UdpClient
等也是如此
现在,如果您想从 HttpWebRequest
的实际代码中确认,您可以看到超时用于创建计时器队列 here. That queue is used to create a timeout timer in GetResponse
but never in BeginGetResponse
。那就是在 DownloadXXXTaskAsync
.
DownloadXXXAsync
中使用的异步选项