异步等待超时

3

我正在编写一个简单的方法,用于验证网页 URL 是否真实存在,并返回 True 或 False。

使用 .NET 4.5 中的新 async await 函数,现在似乎变得非常容易,但如何为异步操作设置超时时间呢?

''' <summary>
''' Returns True if a webpage is valid.
''' </summary>
''' <param name="url">Url of the webpage.</param>
Private Async Function VailiateWebpageAsync(url As String) As Task(Of Boolean)       
    Dim httpRequest As HttpWebRequest
    Dim httpResponse As HttpWebResponse

    httpRequest = CType(WebRequest.Create(url), HttpWebRequest)
    httpRequest.Method = "HEAD" 'same as GET but does not return message body in the response

    Try
        httpResponse = CType(Await httpRequest.GetResponseAsync, HttpWebResponse)
    Catch ex As Exception
        httpResponse = Nothing
    End Try

    If Not IsNothing(httpResponse) Then
        If httpResponse.StatusCode = HttpStatusCode.OK Then
            httpResponse.Dispose()
            Return True
        End If
    End If

    If Not IsNothing(httpResponse) Then httpResponse.Dispose()
    Return False
End Function
4个回答

4
根据作者的评论,我理解他想要设置任何异步操作的超时时间。这是我在.NET 4上使用的方法,可以设置10秒超时时间。在.NET 4.5上语法略有不同,因为他们用Task类替换了TaskEx类的静态方法。
        var getUserTask = serviceAgent.GetAuthenticatedUser();
        var completedTask = await TaskEx.WhenAny(getUserTask, TaskEx.Delay(10000));

        if (completedTask != getUserTask)
        {
            Log.Error("Unable to contact MasterDataService to retrieve current user");
            MessageBox.Show("Unable to contact the server to retrieve your user account.  Please try again or contact support.");
            Application.Current.Shutdown();
        }

这段代码将启动异步任务GetAuthenticatedUser,但不会在该行上等待,因为没有使用await。相反,它会继续执行下一行,并等待getUserTask或者10秒的延迟。哪个先完成,就会导致该行的await返回。我们可以通过检查TaskEx.WhenAny返回的Task或查询getUserTask并查看其状态来确定是否发生了超时。

1

HttpWebRequest有一个Timeout属性,您可以设置:

MSDN: HttpWebRequest.Timeout

如果超时,将抛出一个WebException,并将Status属性设置为Timeout,您可以捕获并处理它。


1
这是一个合理的问题答案 - 但是你如何为异步部分设置超时呢? - George Filippakos
如果在GetResponseAsync中发生超时,那么您的await调用将抛出异常,您可以在普通的catch块中捕获它 - 这是async / await的正常部分。 - Nick Butler
在设置方法后,只需将其正确设置即可 - 它应该自动执行超时。您不需要手动执行此操作。 - James Manning

0

在调用之前,以毫秒为单位设置超时值:

myHttpWebRequest.Timeout = 1234

详情请点击这里


这是一个解决问题的明智答案 - 但是如何为异步部分设置超时时间呢? - George Filippakos

0

你需要通过Task.Delay自己实现超时。

请注意,对于异步调用,HttpWebRequest.Timeout属性将被忽略。这在MSDN中已经明确说明:

==================================

Timeout属性对使用BeginGetResponse或BeginGetRequestStream方法进行的异步请求没有影响。

在异步请求的情况下,客户端应用程序实现自己的超时机制。请参考BeginGetResponse方法中的示例。

==================================


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接