我正在测试连接到Azure Blob Storage的WPF应用程序,以使用TPL(任务)下载一堆图像。 预计在实时环境中,在部署位置将存在与互联网的高度瞬时连接。
我在BlobRequestOptions中设置了重试策略和超时,如下所示:
//Note the values here are for test purposes only
//CloudRetryPolicy is a custom method returning adequate Retry Policy
// i.e. retry 3 times, wait 2 seconds between retries
blobClient.RetryPolicy = CloudRetryPolicy(3, new TimeSpan(0, 0, 2));
BlobRequestOptions bro = new BlobRequestOptions() { Timeout = TimeSpan.FromSeconds(20) };
blob.DownloadToFile(LocalPath, bro);
以上语句在后台任务中按预期工作,我在后台任务和继续任务中有适当的异常处理。
为了测试异常处理和我的恢复代码,我通过拔出网线来模拟互联网断开连接。我已经在UI线程上连接了System.Net.NetworkChange.NetworkAvailabilityChanged事件的方法,我可以按预期检测连接/断开连接并相应地更新UI。
我的问题是:如果我在下载文件时拉出网线(通过blob.DownloadToFile),后台线程就会挂起。它不会超时,不会崩溃,不会抛出异常,什么都没有!在我写作的时候,我已经等了大约30分钟,并且没有响应/处理与后台任务有关。
如果我拉下网线,在下载开始之前,按预期执行。也就是说,我可以看到重试发生,例外提出并提前传递等等。
有没有人经历过类似的行为?有任何提示/建议可以克服这种行为/问题吗?
顺便说一句,我知道我可以在检测到网络连接丢失时取消下载任务,但我不想这样做,因为网络连接可以在超时持续时间内恢复,下载过程可以继续从它被打断的地方。我已经测试了这次自动恢复并且运行良好。
下面是我的代码结构的粗略指示(在语法上不正确,只是流量指示)
btnClick()
{
declare background_task
attach continuewith_task to background task
start background task
}
background_task()
{
try
{
... connection setup ...
blob.DownloadToFile(LocalPath, bro);
}
catch(exception ex)
{
... exception handling ....
// in case of connectivity loss while download is in progress
// this block is not getting executed
// debugger just sits idle without a current statement
}
}
continuewith_task()
{
check if antecedent task is faulted
{
... do recovery work ...
// this is working as expected if connectivity is lost
// before download starts
// this task does not get called if connectivity is lost
// while file transfer is taking place
}
else
{
.. further processing ...
}
}
答案 0 :(得分:2)
我相信Avkash是正确的。此外,要清楚,您基本上永远不会看到网络删除错误,因此在测试它时没有太多意义。根据您处理存储帐户的方式,您将看到大量连接被拒绝,冲突,缺少资源,只读帐户,限制,拒绝访问,甚至DNS解析失败。你应该测试那些。
话虽这么说,但我建议你不要使用RetryPolicy和blob或table存储。对于您实际遇到的大多数错误,它们不能重新开始(例如404,409,403等)。当你有一个重试策略时,默认情况下它会在接下来的2分钟内再尝试4次。例如,重试不良凭证没有意义。
你最好简单地处理错误并自己有选择地重试(超时和限制是唯一有意义的事情)。
答案 1 :(得分:1)
您的问题主要是因为Azure存储客户端库使用下面的文件流类,以及API挂起与Windows Azure Blob客户端库没有直接关系的原因。直接通过网络调用文件流API,当网络电缆突然被移除时,您可以看到完全相同的行为,但是正常移除网络将返回不同的行为。
如果您在互联网上搜索,您会发现流媒体类没有检测到网络丢失,这就是为什么在您的代码中您可以检查网络断开事件然后停止后台流线程。