【问题标题】:Async Await Timeout异步等待超时
【发布时间】:2013-04-16 09:13:36
【问题描述】:

我正在编写一个简单的方法来验证网页 url 是否真实并返回 True 或 False。

在 .NET 4.5 中使用新的异步等待功能现在看起来非常简单,但是如何为异步设置超时?

''' <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

【问题讨论】:

    标签: vb.net .net-4.5 async-await


    【解决方案1】:

    根据作者的评论,我推测他希望能够使任何异步超时。这是我在 .NET 4 上使用的获得 10 秒超时的方法。 .NET 4.5 的语法会略有不同,因为它们将 TaskEx 类上的静态方法替换为 Task 类。

            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并查看其状态来确定是否发生超时

    【讨论】:

      【解决方案2】:

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

      MSDN: HttpWebRequest.Timeout

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

      【讨论】:

      • 这是对这个问题的一个明智的回答——但你如何也为异步部分设置超时?
      • @geo1701 如果在GetResponseAsync 中发生超时,那么您的await 调用将抛出异常,您可以在正常的catch 块中捕获它——这是async / await 的正常部分跨度>
      • 只需在设置方法后立即设置它 - 它应该自行强制执行超时。您不需要手动执行此操作。
      【解决方案3】:

      在调用之前,设置超时值(毫秒):

      myHttpWebRequest.Timeout = 1234
      

      详情为here

      【讨论】:

      • 这是对这个问题的一个明智的回答——但你如何也为异步部分设置超时?
      【解决方案4】:

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

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-09-04
        • 2021-05-25
        • 2021-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多