2013-04-04 112 views
0

我一直在閱讀幾天,我不能完全弄清楚我應該在這裏做什麼。我實際上是一個C#開發人員,VB.NET中的編程有時會有點混亂。除此之外,我試圖在我創建的新項目中實現來自WCF的異步調用。我用結果嘗試了幾種不同的方式,但我想確保我所做的是正確的。ASP.NET(VB.NET 4.5)調用異步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處理程序異步爲好。這樣做似乎不正確?通過這樣做,它看起來像一個異步函數調用一個異步函數。但我在這裏做的方式,我的異步函數返回無效,這應該是避免的。如果需要,我也可以發佈其他方式的例子。謝謝!!

編輯:這工作更好嗎?

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 

末級

EDIT 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 

末級

回答

1

你應該避免async void這是真的。本指南的例外是當您有async事件處理程序時。例如Page_Load

有關此準則的詳細信息,請參閱我的有關Best Practices in Asynchronous Programming的MSDN文章。

這樣看起來不正確嗎?通過這樣做,它看起來像一個異步函數調用一個異步函數。

這是完全正確的。異步代碼將通過您的代碼庫「增長」。正確的解決方案是使SetupPage a Task返回功能和await它在Page_Load(這是async void /子)。

編輯:

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 
+0

謝謝斯蒂芬。我有兩個問題,第一個是我想簡化我的解決方案。另一個將頁面分解爲邏輯塊,我認爲如果將Page_Load更改爲異步,我可以做到這一點,但是我將失去如何組織我的代碼。我編輯了我的帖子,也許現在效果更好? – eXecute 2013-04-04 14:43:17

+0

「我會失去我如何組織我的代碼」對我沒有任何意義。我檢查了你的新代碼,但支持我的建議,只在事件處理程序中使用'async void'; 'SetupPage'應該是一個'異步任務'功能。 – 2013-04-04 14:47:09

+0

當然,我正在反思這一點。也許我需要回到這裏的基礎知識......編輯3,我相信*你在說什麼? – eXecute 2013-04-04 14:53:06

1

由於幸運的是,我只是posted about Async Sub昨天。長話短說,在你的情況下,如果你使用Async Sub,一遇到await,控制將立即恢復到調用方法。因此,您的page_Load處理程序將在SetupPage完成之前結束。如果您希望Page_Load等到SetupPage異步完成,則需要將SetupPage更改爲返回Task的函數,然後將Page_Load中的Await SetupPage(導致Page_Load)設置爲Async。

Async Sub在事件處理程序上有效。盧西安在他最近的Async Patterns post中討論了這一點。你可能還想看看去年的Async talk from ASP.Net Conf,關於在ASP.Net/WCF中使用Async的特殊注意事項。

+0

我見過這些,謝謝!也許我只是需要更多的時間重新閱讀。 – eXecute 2013-04-04 14:23:13