非同步程式, Asynchronous Programming
現在要在VB11裡開發非同步程式(Asynchronous Programming)變的很簡單了。在VB11中新增 Async / Await 關鍵字。
範例程式來源:101 Samples in C# and Visual Basic
VB 10: await - Serial Network Requests
Public Sub AsyncIntroSerialBefore()
Dim client As New WebClient()
AddHandler client.DownloadStringCompleted, AddressOf AsyncIntroSerialBefore_DownloadStringCompleted_1
client.DownloadStringAsync(New Uri("http://www.weather.gov"))
End Sub
Sub AsyncIntroSerialBefore_DownloadStringCompleted_1(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
WriteLinePageTitle(e.Result)
Dim client As New WebClient()
AddHandler client.DownloadStringCompleted, AddressOf AsyncIntroSerialBefore_DownloadStringCompleted_2
client.DownloadStringAsync(New Uri("http://www.weather.gov/climate/"))
End Sub
Sub AsyncIntroSerialBefore_DownloadStringCompleted_2(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
WriteLinePageTitle(e.Result)
Dim client As New WebClient()
AddHandler client.DownloadStringCompleted, AddressOf AsyncIntroSerialBefore_DownloadStringCompleted_3
client.DownloadStringAsync(New Uri("http://www.weather.gov/rss/"))
End Sub
Sub AsyncIntroSerialBefore_DownloadStringCompleted_3(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
WriteLinePageTitle(e.Result)
End Sub
VB 11: await - Serial Network Requests
Public Async Sub AsyncIntroSerial()
Dim client As New WebClient()
WriteLinePageTitle(Await client.DownloadStringTaskAsync(New Uri("http://www.weather.gov")))
WriteLinePageTitle(Await client.DownloadStringTaskAsync(New Uri("http://www.weather.gov/climate/")))
WriteLinePageTitle(Await client.DownloadStringTaskAsync(New Uri("http://www.weather.gov/rss/")))
End Sub
如果要在要 Visual Studio 2010 for Visual Basic 10 環境下去使用 Async / Await 關鍵字,必須去安裝 Visual Studio Async CTP (Version 3) 套件。當然,也支援非同步的除錯及單元測試(MSTest與xUnit支援良好)。
請參考:
- Asynchronous Programming Developer Center
- Announcing the Async CTP for Visual Basic (and also Iterators!)
Iterators
Iterator 首先出現在 C#,在 VB 10 之前未與 C# 同步使用此方法,但在 VB 11 裡終於可以 C# 同步使用。想了解 Iterator 方法,我想最好先從 Iterator (C# 程式設計手冊) 下手,因為 VB10 之前沒有 Iterator 方法,所以去看 C# 的資料在所難免。其實之前我根本沒有注意過 Inerator 方法,直到在 MVC 3 for C# 的程式碼中,看到有人使用 Iterator 方法,結果我怎麼轉就是無法在 VB 實作、執行,後來才發現原來 VB 10 根本就無此方法,這讓我非常頭痛。在 Visual Studio 11 開一個 Console Application ,輸入以下測試程式:
Module Module1
' 取得MyPictures的路徑
Dim PicPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
Sub Main()
' 呼叫 GetPics() 方法
For Each fn In GetPics(PicPath)
Console.WriteLine(fn)
Next
End Sub
' 用 Iterator 宣告函數
Iterator Function GetPics(PicPath As String) As IEnumerable(Of String)
For Each pic In IO.Directory.GetFiles(PicPath, "*.jpg")
' 用 Yield 而非 Return
Yield pic
Next
End Function
End Module
![]() |
| 圖一:Visual Basic 11 and Iterator - Yield |
P.S 在Windows 8 CP Beta執行結果會是空白,那是因為它的 Pictures 之下沒有預設圖片。
命名空間 Global
可以同時使用 Namespace 和 Global 關鍵字。Namespace Global Namespace Global.<NamespaceName>
可參考:
- Announcement: Namespace Global
- Namespaces in Visual Basic
- [Visual Studio]VB 11.0 New Feature - Namespace Global (中文)
覆寫方法中的選擇性參數
在 VB 10 之前版本,覆寫的方法不能增加選擇性參數,例如:Sub f(x As Integer) End Sub ' 覆寫版本 Sub f(x As Integer, Optional y As Integer = 0) End Sub
現在 VB 11 以上的程式碼可以正常運作。
無限制(Command-line)錯訊訊息
之前為了效能原因,Visual Basic IDE 最大只會輸出 101 條錯誤。現在在 command-line 編譯器移除此限制。呼叫者資訊屬性 ( Caller Info Attributes)
編譯器現在會識別三個特別屬性:<CallerMemberName>、<CallerLineNumber>、和<CallerFilePath>。例如在執行Log情況下,在呼呼方法時,允許你能有名稱(name)、行號(line number)、或檔案路徑(file path)透過選擇性參數傳遞給處理Log函式。另一個很好的範例是,當我們在實作 INotifyPropertyChanging介面時:
Class C
Implements INotifyPropertyChanged
Dim backing As New Dictionary(Of String, Object)
Property p As String
Get
Return GetProp(Of String)()
End Get
Set(ByVal value As String)
SetProp(value)
End Set
End Property
' 在選擇性參數加上 CallerMemberName 屬性
Public Function GetProp(Of T)(<callermembername()> Optional prop As String = Nothing) As T
Debug.Assert(prop IsNot Nothing)
Try
Return CType(backing(prop), T)
Catch ex As KeyNotFoundException
Return CType(Nothing, T)
End Try
End Function
' 在選擇性參數加上 CallerMemberName 屬性
Public Sub SetProp(Of T As IComparable(Of T))(value As T,
<callermembername()> Optional prop As String = Nothing)
Try
Dim oldvalue = CType(backing(prop), T)
If value.CompareTo(oldvalue) = 0 Then Return
Catch ex As KeyNotFoundException
End Try
backing(prop) = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(prop))
End Sub
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
End Class
簡化程式碼
在 IDE 中將不會插入 "ByVal 在方法中,除非你明確輸入或宣告它。另外,也不會去插入完整名稱(fully-qualified name),例如:VB 10:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
VB 11:
' 此範例中,System 早已經在專案匯入 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
當你按下Enter要實作介面時,以上也會自動運作在所有介面方法。
查看呼叫階層(Call Hierarchy)
在VB 11,如果你點擊方法名稱,你將會看到一個新選項 "View Call Hierarchy",它能讓你查看整個方法所呼叫的層級。![]() |
| 圖二:New Option "View Call Hierarchy" |
![]() |
| 圖三:Call Hierarchy 視窗 |
影片參考:



沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。