非同步程式, 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 視窗 |
影片參考:
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。