top
Loading...
與VisualBasic.NET一起使用.NETFramework
使用.NET Framework,Microsoft Visual Basic開發人員可以創建健壯的、在先前的Visual Basic版本中很難編寫的應用程序。本文將討論使用.NET Framework的好處,并且將包括一些功能強大的、Visual Basic開發人員可以與該框架一起使用的特性,包括多線程和線程池(thread pooling)、Windows服務和文件系統監控等。

為什么使用框架

單詞框架(framework)有幾種含意。在這種情況中,它指的是創建和運行應用程序的基礎。擁有這樣的基礎使得創建應用程序變得更容易,而同時使用了一個一致的、簡化的程序設計模型。

作為一個Visual Basic 6.0開發人員,你對于這種程序設計語言感覺很滿意,它使得創建各種應用程序變得很容易。Visual Basic語言本身提供了固有的數據類型,如 Integer, Long和String,以及一些最常用的函數,如字符串處理和數據類型轉換等。當你的應用程序變得更復雜時,你可以使用Win32 API來完成標準的Visual Basic函數所不能實現的功能-如獲取任意的注冊鍵和數值。在許多情況中,你還可以使用COM(Component Object Model,組件對象模型)組件庫來擴展應用程序的功能;最明顯的例子是ADO(ActiveX Data Objects)庫,你的應用程序可以使用它來進行數據訪問。

雖然Visual Basic足夠靈活,可以提供這些不同的可擴展性機制,但這種靈活性仍然需要你學習幾種復雜的API體系結構。你需要了解Win32如何工作,以及如何在Visual Basic中調用它們,這可能會是一個既費時又容易出錯的任務。你還需要了解如何在Visual Basic中使用各種COM組件,每個COM組件都有一個不同的對象模型。

最后,當你使用Win32 API、ADO,也可能使用許多其他COM組件,創建自己的Visual Basic應用程序時,你需要管理這些應用程序的部署以及它們的相關性。一個典型的Visual Basic應用程序的相關性列表所包括的遠遠多于Visual Basic運行時(runtime);它必須包括應用程序使用的所有對象庫,如ADO 2.6。

公共框架背后的想法是解決這些問題,并使得用戶創建健壯的應用程序變得更容易,而無需學習多種不同的API體系結構,并且無需部署和處理多種對象庫的版本問題。

什么是.NET Framework

術語.NET Framework指的是構成Microsoft .NET平臺開發基礎的一組技術。這一組中的關鍵技術是運行時(runtime)和類庫,如圖1所示。


圖 1. .NET Framework由.NET運行時和類庫組成

運行時負責管理代碼,在執行時向它提供服務,這與Visual Basic 6.0運行時的作用類似。.NET程序設計語言-包括Visual Basic .NET、Microsoft Visual C#、C++管理的擴展,以及多種來自不同開發商的程序設計語言-通過一組公共的統一類來利用各種服務和特性。

.NET統一類提供了創建應用程序的基礎,而不管你使用何種語言。無論你只是簡單地連接一個字符串,還是創建一個Windows服務或多層的基于網絡的應用程序,你都要用到這些統一類。

統一類為訪問平臺的功能性提供了一種一致的方法。一旦你學會了使用類庫,你就會發現所有任務都遵循同一個一致的體系結構。要編寫自己的應用程序,你無需學習和掌握不同的API體系結構。

由于.NET Framework,部署Visual Basic .NET應用程序變得更容易了。與Visual Basic 6.0應用程序不同,你無需配置各種相關性,如單獨的數據訪問庫、XML語法分析器和網絡API,因為所有這些功能都是.NET Framework的組成部分。

通過在統一的、集成的框架上創建自己的應用程序,你可以實現學習這種框架所花費時間的最大回報,并且你將擁有更多容易部署和使用的健壯的應用程序。

.NET Framework與Visual Basic .NET

Visual Basic 6.0運行時在簡化許多公共的程序設計任務方面非常重要。但是簡化這一層意味著,在擁有Visual Basic可以使用的打包程序之前,你不能使用新的操作系統特性,如DirectX。作為一個Visual Basic開發人員,你從.NET Framework獲得的最重要的益處是,可以使用一致的程序設計模型既直接又容易地訪問.NET平臺。這意味著,你可以使用Visual Basic .NET創建很難或不可能使用Visual Basic 6.0創建的應用程序。作為一個Visual Basic 6.0開發人員,現在你將對能夠使用與其他平臺語言相同的特性和功能而贊賞不已。例如,為了創建Windows服務,你無須再用Microsoft Visual C++來編寫它,你也無須求助于黑客或組裝機。你可以優雅、干凈、容易地使用Visual Basic .NET完成這項工作。為了給你一些使用.NET Framwork的例子,我們將討論在你的應用程序中可能需要執行的4個常見任務:跟蹤與事件記錄、多線程、文件系統監控和創建Windows服務。

跟蹤與事件記錄

當創建一個健壯的應用程序的時候,你必須密切注意診斷和故障排除機制。代表性地,這包括編寫處理打開輸出目標(事件記錄或文件)的跟蹤組件,編寫跟蹤消息和關閉輸出目標。然后通過自己的代碼調用關于這個組件的方法,將文本傳遞給記錄。你將所有的時間和精力花在了創建跟蹤和記錄子系統上,這最終并不會對解決商務問題有所貢獻,但這是創建應用程序所必需的。

.NET Framework包括類和其他數據類型,通過向你提供記錄基礎設施,使得記錄跟蹤消息變得很容易。圖2給出了用于跟蹤的.NET Framework類。


圖2. 在使用.NET Framewok中用到的跟蹤工具

類是System.Diagnostics名稱空間的一部分。Trace類提供了幾個共享的方法。例如,Write方法允許你記錄特定消息,而Assert方法允許你在特定的條件為假的情況下記錄一條消息。Trace類將消息輸出到Listeners集合中的對象。這個集合中的每個對象都屬于繼承自TraceListener的一個類。EventLogTraceListener 將消息寫入事件記錄,而TextWriterTraceListener則是將消息寫入到一個文本文件中,默認情況下,DefaultTraceListener的一個實例被添加到Trace類的Listeners集合中。

除了標準的監聽程序以外,你可以實施自己跟蹤監聽程序。例如,你希望接收來自在防火墻后面的遠程機器上運行的應用程序的跟蹤輸出。你可以編寫一個跟蹤監聽程序,通過HTTP全球向你的服務器發送跟蹤消息。這將會影響你的應用程序的性能,但只會在啟用跟蹤時才會對性能有所影響。

代表性地,你需要有能力在編譯的二進制文件中包括或去除跟蹤代碼。為了在Visual Basic 6.0中做到這一點,你需要使用編譯常量,并在#If語句中包含所有的跟蹤代碼,這使得代碼很難理解和維護。利用.NET Framework,你只需在項目屬性(Project Properties)對話框中將TRACE編譯常量設為on或off狀態;你無需在#If語句中包括跟蹤代碼。

另一個普遍期望的跟蹤特性是跟蹤水平設置,這包括不同的跟蹤設置-例如, Severe(嚴重)、Error(錯誤)、Warning(警告)和Information(信息)-這些設置對記錄哪些信息進行控制。你可以使用跟蹤組件啟動時所讀取的注冊表數值對此進行控制。對于.NET Framework,這是完全內置的功能。你可以設置一個注冊表數值來控制你當前的應用程序的記錄水平,比如,只有在跟蹤水平被設置為Severe(嚴重)的情況下,才使用Trace.WriteIf和Trace.WriteLineIf來記錄消息。

集成的跟蹤和記錄特性極大地增強了生產力,因為你只需使用內置的特性,將精力集中在編寫真正的應用程序代碼上。

多線程應用程序

.NET Framework的一個很重要的特性是,可以在不使用第三方工具或不支持的Visual Basic技巧情況下,使用Visual Basic創建多線程應用程序。.NET Framework的多線程支持是由System.Threading名稱空間中的類和接口提供的,因此所有的.NET語言都能夠以相同的方式創建和處理線程。System.Threading.Thread是一個核心類,提供了對創建和控制線程的支持。要創建一個線程,你可以創建一個新的System.Threading.Thread對象,將構造函數傳遞給ThreadStart代理。這個代理提供了這個線程開始執行的方法。當你準備啟動這個新的線程時,可以調用Thread.Start() (請參閱清單1)。

當你開始創建多線程應用程序時,你很快就會認識到需要控制對共享資源的訪問,如共享的類變量。.NET Framework還包括幾個類和數據類型,你可以使用它們對兩個線程執行的動作進行同步。

在最簡單的情況中,你由一個需要從不同的線程中進行更新的共享變量。要這樣做,你可以使用System.Threading.Interlocked類。例如,你可以通過編寫Interlocked.Increment(num)或Interlocked.Decrement(num)分別使名為num的共享變量遞增或遞減。你還可以使用Interlocked將變量設為某一特定值,或檢查兩個變量是否相等。除了這種簡單情況以外,你可以使用.NET Framework類來執行更復雜的線程同步,如事件和互斥體的同步-所有都來自于.NET Framework內部,而無須使用Win32 API。.

Imports System.IO
'The namespace System.Threading
'contains the Thread class
Imports System.Threading
Module Module1
Private count As Long
Sub Main()
'Create the ThreadStart delegate
Dim tStart As ThreadStart = New _
ThreadStart(AddressOf StartCounting)
'Create the thread
Dim t1 As Thread = New Thread(tStart)
Console.WriteLine("Enter q to quit")
t1.Start() 'start the thread
While (Console.Read() <> asc("q"))
'repeat the loop until the user enters q
End While
t1.Stop() 'tell thread to stop processing
t1.Join() 'wait until the thread finishes
End Sub
Sub StartCounting()
Do
'use Interlocked.Increment in case
'another thread is accessing the same variable
Interlocked.Increment(count)
Console.WriteLine( _
"After incrementing count is : {0}", count)
Thread.Sleep(200)
Loop
End Sub
End Module

清單1. 使用Visual Basic .NET創建線程

你創建了一個新線程,將它傳遞給一個ThreadStart代理。然后調用Thread.Start()啟動這個線程。你可以通過調用Thread.Stop()來中止這個線程,然后調用Thread.Join()等待它完成關閉操作。一個線程可以使用System.Threading.Interlocked來使變量遞增或遞減。

此外,.NET Framework提供了一個方便的機制來對工作排隊,并將起分配給線程池中的某個線程。在處理多個并發工作項目或工作請求的服務器應用程序中,這非常有用。例如,對于等待輸入文件,然后將它們導入到數據庫中去的應用程序,可能會對每個輸入文件進行排隊,以在線程池中的某個單獨的線程上進行處理。System.Threading.ThreadPool類允許你使用共享的QueueUserWorkItem方法對工作進行排隊。以前要這樣做,你必須得創建和管理自己的線程池。你又需要在基礎設施工作而不是在解決商務問題上花大量的時間和精力。

文件系統監控

我曾經遇到過一些應用程序,需要等待和處理某個特定目錄中的文件-例如,將數據從文件導入到數據庫中去的應用程序。數據文件可以從某個大型機上下載,或者被轉移到某個輸入目錄中,該應用程序將它們導入到數據庫中。你不用經常地輪詢該目錄檢查是否有新文件,可以等待生成新文件的通知。你可以在Visual Basic 6.0中使用Win32 API來做到這一點,而在Visual Basic .NET中你可以使用.NET Framework類來做這項工作。但是在.NET中實施文件監控與在.NET中完成其他工作的方法更加一致,因此學習曲線是最小的。

你可以使用System.IO.FileSystemWatcher .NET類對文件系統進行監視。它提供了一些屬性,允許你設置監控的路徑,指定是對文件還是子目錄層次的變化感興趣。System.IO.FileSystemWatcher還允許你指定需要監控的文件名和文件類型(例如,*.xml是指監控所有XML文件的變化)。最后,你可以指定感興趣的變化類型-例如,只對新建文件,文件屬性的變化或文件大小的變化(請參閱清單2)感興趣。

在你設置了監控內容后,你需要鉤住用于感興趣的各種事件的事件處理程序。FileSystemWatcher事件有Changed、Created、Deleted、Error和Renamed。要處理某個事件,首先你需要編寫一個與FileSystemEventHandler代理相同聲明的事件處理程序,然后將這個處理程序添加到FileSystemWatcher類中。這個基于代理的體系結構允許你為同一個事件添加多個處理程序,或者對于多個事件使用同一個處理程序-而你不能使用Visual Basic 6.0做到這一點。

'System.IO contains the
'file monitoring classes and types
Imports System.IO
Module Module1

Sub Main()
'FileSystemWatcher does the real work
Dim fw As New FileSystemWatcher()
'WaitForChangedResult is what you
'get back when a change occurs
Dim result As WaitForChangedResult
'set the path to monitor
fw.Path = "C:WINNT"
'tell it whether to watch files or directories
fw.Target = WatcherTarget.File
'tell it whether to include subdirs
fw.IncludeSubdirectories = False
'hook up handlers
AddHandler fw.Created,New FileSystemEventHandler(AddressOf OnFileNotify)
'enable the watcher
fw.Enabled = True
Do
Console.WriteLine("Beginning to monitor")
'this is where we actually wait
'waiting blocks execution for the specified timeout
result = fw.WaitForChanged(WatcherChangeTypes.All, 60000)
Console.WriteLine("Hit Enter to continue q to quit")
Loop While (Console.ReadLine <> "q")
End Sub
'This is the delegate that gets
'called when a file is created
Public Sub OnFileNotify(ByVal source As Object, ByVal e As FileSystemEventArgs)
Console.WriteLine( "Notification received for file {0}, change type is {1}", _
e.FullPath, e.ChangeType)
End Sub
End Module

清單2. 使用FileSystemWatcher監控某個文件夾是否有新文件。

你可以創建一個FileSystemWatcher,然后設置它的屬性。你可以使用AddHandler將FileSystemEventHandler代理與各種FileSystemWatcher事件關聯起來,如Created。然后你就可以啟用FileSystemWatcher,然后調用WaitForChanged。該調用將在變化發生或達到指定的超時時返回。

創建Windows服務

當你要創建一個Windows服務時,你必須使用Visual C++或在Visual Basic中使用srvany.exe或第三方工具來創建該服務。任何一種方法,你都沒有在Visual Basic中編寫自己的服務,你只是正在Visual Basic運行時的外部添加更多從屬組件。

如果你使用C++或C語言,在不使用活動模版庫(Active Template Library)的情況下從頭編寫一個Windows服務,你將不得不編寫一小段代碼來協調你的服務與服務控制器(Service Control Manager,SCM)之間的往來通信,SCM用來處理服務的啟動、暫停、繼續和停止。.NET Framework通過提供System.ServiceProcess.ServiceBase類,使得實現一個服務變得很容易。要編寫一個服務,你可以從這個類繼承,重載它的某些方法,設置它的屬性,然后就大功告成了!

你可能要重載的一些方法包括:OnStart、OnStop、OnPause和OnContinue。通常你需要載啟動工作線程(worker thread)的位置重載OnStart,在需要取消這個工作線程的位置重載OnStop。在你創建了自己的服務后,你就可以使用SCM安裝和注冊這個服務。這是另一個領域,.NET Framework中的基類提供了大部分所需的工作。你可以創建一個繼承自System.Configuration.Install.Installer的類,從System.ServiceProcess.ServiceInstaller中例示對象,然后設置它的屬性,如服務啟動模式和服務名稱。這使得.NET安裝實用工具installUtil.exe能夠安裝(和刪除)你的服務,而你無需編寫額外的代碼。

當你開始使用Visual Studio .NET時,你將會發現Visual Studio .NET使得使用.NET Framework變得更容易。Visual Studio .NET允許你創建Windows服務(擁有安裝程序(installer)),監控文件系統的變化,寫入事件記錄 - 所有都是使用設計器和組件而不是編寫代碼來完成。例如,要將一個安裝程序添加到自己的服務項目中,你只需選中服務設計器避免,然后單擊屬性(Properties)窗口(見圖3)底部的添加安裝程序(Add Installer)。這將添加一個新模塊ProjectInstaller.vb,該模塊包括安裝該服務所需的全部代碼。你可以使用設計器(見圖4),對安裝選項,如啟動模式進行自定義


圖3. 使用Visual Studio .NET給你的服務項目添加安裝程序



圖4. 使用設計器,對安裝選項,如StartType進行自定義

結論

.NET Framework使得你能夠利用Visual Basic .NET,很容易地開發健壯地應用程序。它使得你可以將重點放在學習一種相容的程序設計模型上,并且使得你可以直接訪問底層的.NET平臺。利用Visual Basic .NET和.NET Framework,你可以使自己的應用程序達到前所未有的水平。


作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗