0

我已经阅读了好几天,我不太清楚我应该在这里做什么。我实际上是一名 C# 开发人员,使用 VB.NET 进行编程有时会让人有些困惑。除此之外,我正在尝试在我在这里创建的新项目中实现来自 WCF 的异步调用。我已经尝试了几种不同的结果,但我想确保我所做的事情是正确的。

根据我的阅读,您永远不应该在异步方法中返回 void,因此我正在尽最大努力避免它。除了所有这些,我想我只是想知道这是否是构建此页面的有效方法。在我构建它时,它将从 WCF 调用不止一种方法。

Public Class _DefaultReservation
Inherits System.Web.UI.Page

Dim wcfReservation As WCFReservation.WDReservationClient

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    SetupPage()

End Sub


Private Async Sub SetupPage()

    wcfReservation = DirectCast(Master, LoggedInMaster).wcfReservation

    Dim resData As String = Await wcfReservation.GetDataAsync(123)
    Response.Write(resData)

End Sub

End Class

我想令人困惑的是,如果我将该代码放在异步函数中并返回任务,我也必须将 page_load 处理程序标记为异步。这样做似乎不对?通过这样做,似乎异步函数正在调用异步函数。但是我在这里做的方式是,我的异步函数返回 void,这应该避免。如果需要,我也可以发布另一种方式的示例。谢谢!!

编辑:这更好用吗?

Imports System.Threading.Tasks

公共类 _DefaultReservation 继承 System.Web.UI.Page

Dim wcfReservation As WCFReservation.WDReservationClient

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    SetupPage()

End Sub


Private Async Sub SetupPage()

    wcfReservation = DirectCast(Master, LoggedInMaster).wcfReservation

    Dim getDataResult = Await GetDataAsync()
    Response.Write(getDataResult)

End Sub

Private Function GetDataAsync() As Task(Of String)

    Return wcfReservation.GetDataAsync(123)

End Function

结束类

编辑 3:

Imports System.Threading.Tasks

公共类 _DefaultReservation 继承 System.Web.UI.Page

Dim wcfReservation As WCFReservation.WDReservationClient

Protected Async Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    wcfReservation = DirectCast(Master, LoggedInMaster).wcfReservation

    Dim result As String = Await wcfReservation.GetDataAsync(1234)
    Response.Write(result)

End Sub

结束类

4

2 回答 2

1

确实应该避免async void。本指南的例外情况是您有async事件处理程序。

比如Page_Load

有关此指南的更多信息,请参阅我的 MSDN 文章“异步编程最佳实践”

这样做似乎不对?通过这样做,似乎异步函数正在调用异步函数。

这是完全正确的。异步代码将通过您的代码库“增长”。正确的解决方案是制作SetupPage一个Task-returning 函数并将await其放入Page_Load(这是一个async void/Sub)。

编辑:

Imports System.Threading.Tasks

Public Class _DefaultReservation Inherits System.Web.UI.Page

  Dim wcfReservation As WCFReservation.WDReservationClient

  Protected Async Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim getDataResult = Await GetDataAsync()
    Response.Write(getDataResult)
  End Sub

  Public Function GetDataAsync() As Task(Of String)
    wcfReservation = DirectCast(Master, LoggedInMaster).wcfReservation
    Return wcfReservation.GetDataAsync(123)
  End Function

End Class
于 2013-04-04T14:13:48.063 回答
1

幸运的是,我昨天刚刚发布了关于 Async Sub的信息。长话短说,在您的情况下,如果您使用 Async Sub,一旦遇到等待,控制就会恢复到调用方法。因此,您的 page_Load 处理程序将在 SetupPage 完成之前结束。如果您想让 Page_Load 等到 SetupPage 异步完成,您需要将 SetupPage 更改为返回 Task 的函数,然后将 Page_Load 中的 Await SetupPage(导致 Page_Load)更改为 Async。

Async Sub 在事件处理程序上有效。Lucian 在他最近的Async Patterns 帖子中详细讨论了这一点。您可能还想查看去年ASP.Net Conf 的 Async 演讲,了解有关将 Async 与 ASP.Net/WCF 结合使用的特殊注意事项。

于 2013-04-04T14:14:25.977 回答