In the button’s click event, place the following two lines of code: Dim sngAvg As SinglesngAvg = GetAverage0, 100 Then put the following function in the form’s code: Private Function Get
Trang 1Figure 9-8
My
The Mykeyword is a novel concept to quickly give you access to your application, your users, yourresources, the computer, or the network on which the application resides The Mykeyword has beenreferred to as a way of speed-dialing common but complicated resources that you need access to Usingthe Mykeyword, you can quickly get access to a wide variety of items such as user details or specific settings of the requestor’s browser
Though not really considered a true namespace, the Myobject declarations that you make work the same
as the NET namespace structure you are used to working with To give you an example, let’s first look
at how you get at the user’s machine name using the traditional namespace structure:
Environment.MachineName.ToString()
For this example, you simply need to use the Environmentclass and use this namespace to get at the
MachineNameproperty Now let’s look at how you would accomplish this same task using the new My
keyword:
My.Computer.Info.MachineName.ToString()
As you are looking at this example, you might be wondering what the point is if the example, which isusing My, is lengthier than the first example that just works off of the Environmentnamespace Justremember that it really isn’t about the length of what you type to get access to specific classes, butinstead is about a logical way to find often accessed resources without the need to spend too much timehunting them down Would you have known to look in the Environmentclass to get the machine name
of the user’s computer? Maybe, but maybe not Using My.Computer.Info.MachineName.ToString()
is a tremendously more logical approach, and once compiled, this namespace declaration will be set towork with the same class as previously without a performance hit
BookTextStringSystemSimpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 2If you type the Mykeyword in your Windows Forms application, you will notice that IntelliSense provides you with six items to work with —Application, Computer, Forms, Resources, User, and
WebServices Though this new keyword works best in the Windows Forms environment, there are stillthings that you can use in the Web Forms world If you are working for a Web application, then you will have three items off of the Mykeyword —Application, Computer, and User Each of these is broken down in the following sections
ApplicationContext Returns the contextual information about the thread of
the Windows Forms application
AssemblyInfo Provides quick access to the assembly of the Windows
Forms You can get at assembly information such as version number, name, title, copyright information, andmore
ChangeCurrentCulture A method that allows you to change the culture of the
current application thread
ChangeCurrentUICulture A method that allows you to change the culture that is
being used by the Resource Manager
CurrentCulture Returns the current culture which is being used by the
current thread
CurrentDirectory Returns the current directory for the application
CurrentUICulture Returns the current culture that is being used by the
Resource Manager
Deployment Returns an instance of the ApplicationDeployment
object, which allows for programmatic access to theapplication’s ClickOnce features
IsNetworkDeployed Returns a Booleanvalue which indicates whether the
application was distributed via the network using the ClickOnce feature If True, then the application wasdeployed using ClickOnce — otherwise False
event log listeners
MainForm Allows access to properties of the main form (initial
form) for the application
Table continued on following page
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 3Property/Method Description
OpenForms Returns a FormCollectionobject, which allows access
to the properties of the forms which are currently open
SplashScreen Allows you to programmatically assign the splash screen
for the application
While there is much that can be accomplished using the My.Applicationnamespace, for an example
of its use, let’s focus on the use of the AssemblyInfoproperty This property provides access to theinformation that is stored in the application’s AssemblyInfo.vbfile as well as other details about the class file In one of your applications, you can create a message box that is displayed using the following code:
MessageBox.Show(“Company Name: “ & My.Application.AssemblyInfo.CompanyName & _vbCrLf & _
“Description: “ & My.Application.AssemblyInfo.Description & vbCrLf & _
“Directory Path: “ & My.Application.AssemblyInfo.DirectoryPath & vbCrLf & _
“Copyright: “ & My.Application.AssemblyInfo.LegalCopyright & vbCrLf & _
“Trademark: “ & My.Application.AssemblyInfo.LegalTrademark & vbCrLf & _
“Name: “ & My.Application.AssemblyInfo.Name & vbCrLf & _
“Product Name: “ & My.Application.AssemblyInfo.ProductName & vbCrLf & _
“Title: “ & My.Application.AssemblyInfo.Title & vbCrLf & _
“Version: “ & My.Application.AssemblyInfo.Version.ToString())
From this example, you can see that we can get at quite a bit of information concerning the assembly ofthe application that is running Running this code will produce a message box similar to the one shown
in Figure 9-9
Figure 9-9Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 4Another interesting property to look at from the My.Applicationnamespace is the Logproperty Thisproperty allows you to work with the log files for your application For instance, you can easily write tothe system’s Application Event Log by first changing the application’s app.configfile to include thefollowing:
End Sub
You could also just as easily use the WriteExceptionEntrymethod in addition to the WriteEntry
method After running this application and looking in the Event Viewer, you will see the event shown inFigure 9-10
The previous example showed how to write to the Application Event Log when working with the objectsthat write to the event logs In addition to the Application Event Log, there is also a Security Event Log and
a System Event Log It is important to note that when using these objects, it is impossible to write to theSecurity Event Log, and it is only possible to write to the System Event Log if the application does it undereither the Local System or Administrator accounts
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 5Figure 9-10
In addition to writing to the Application Event Log, you can also just as easily write to a text file Just aswith writing to the Application Event Log, writing to a text file also means that you are going to need tomake changes to the app.configfile
Trang 6Version=8.0.1200.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”initializeData=”FileLogWriter” />
Microsoft.VisualBasic.MyServices.Log.WindowsFormsSourceInformation 1 Entered Form1_Load
Though split here on two lines (due to the width of the paper for this book), you will find this tion in a single line within the log file By default it is separated by tabs, but you can also change thedelimiter yourself by adding a delimiter attribute to the FileLog section in the app.configfile This is:
informa-<add name=”FileLog”
type=”System.Diagnostics.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.1200.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”
Audio This object allows you to work with audio files from
your application This includes starting, stopping, andlooping audio files
Clipboard This object allows you to read and write to the clipboard
Clock This allows for access to the system clock to get at GMT
and the local time of the computer that is running theapplication You can also get at the tick count, which isthe number of milliseconds that has elapsed since thecomputer was started
Table continued on following page
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 7Property Description
FileSystem This object provides a large collection of properties and
methods that allow for programmatic access to drives,folders, and files This includes the ability to read, write,and delete items in the file system
amount of memory, the operating system type, whichassemblies are loaded, and the name of the computeritself
Keyboard This object provides access to knowledge of which
keyboard keys are pressed by the end user Also included
is a single method, SendKeys, which allows you to sendthe pressed keys to the active form
Mouse This provides a handful of properties that allow for
detection of the type of mouse installed, and providessuch details as whether the left and right mouse buttonshave been swapped, whether a mouse wheel exists, anddetails on how much to scroll when the user uses thewheel
name of the computer
Network This object provides a single property and some methods
to enable you to interact with the network to which thecomputer where the application is running is connected.With this object, you can use the IsAvailableproperty
to first check that the computer is connected to a network If this is positive, the Networkobject allowsyou to upload or download files, and ping the network
Ports This object can provide notify one if there are available
ports as well as allowing for access to the ports
Printers This object allows determination of which printers are
available to the application as well as provides the ability
to define default printers and print items to any of theprinters available
Registry This object provides programmatic access to the registry
and the registry settings Using the Registryobject, youcan determine if keys exist, determine values, changevalues, and delete keys
Screen Provides the ability to work with one or more screens
which may be attached to the computer
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 8There is a lot to the My.Computernamespace, so it is impossible to touch upon most of it For an example of using this namespace, let’s take a look at the FileSystemproperty The FileSystem
property allows for you to easily and logically access drives, directories, and files on the computer
To illustrate the use of this property, first start off by creating a Windows Form with a DataGridView
and a Buttoncontrol It should appear as shown in Figure 9-11
Figure 9-11
This little application will look in the user’s My Music folder and list all of the wma files found therein.Once listed, the user of the application will be able to select one of the listed files, and after pressing thePlay button, the file will be launched and played inside Microsoft’s Windows Media Player
The first step after getting the controls on the form in place is to make a reference to the Windows MediaPlayer DLL You will find this on the COM tab, and the location of the DLL is C:\WINDOWS\System32\wmp.dll This will give you an object called WMPLibin the References folder of your solution
You might be wondering why you would make a reference to a COM object in order to play a wma filefrom your application instead of using the My.Computer.Audionamespace that is provided to you TheAudio property only allows for the playing of wav files, because to play wma, mp3, and similar files,the user must have the proper codecs on his or her machine These codecs are not part of the Windows
OS, but are part of Windows Media Player
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 9Now that the reference to the wmp.dllis in place, let’s put some code in the Form1_Loadevent.
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
For Each MusicFile As String _
In My.Computer.FileSystem.GetFiles _(My.Computer.FileSystem.SpecialDirectories.MyMusic, True, “*.wma”)Dim MusicFileInfo As System.IO.FileInfo = _
My.Computer.FileSystem.GetFileInfo(MusicFile.ToString())Me.DataGridView1.Rows.Add(MusicFileInfo.Directory.Parent.Name & _
“\” & MusicFileInfo.Directory.Name & “\” & MusicFileInfo.Name)Next
as well By default, this is set to False, but it has been changed to Truefor this example The lastparameter defines the wildcard that should be used in searching for elements In this case, the value ofthe wildcardis *.wma, which instructs the GetFilemethod to get only the files that are of type wma.Once retrieved with the GetFilemethod, the retrieved file is then placed inside the DataGridView
control, again using the My.Computer.FileSystemnamespace to define the value of the item placedwithin the row
Once the Form1_Loadevent is in place, the last event to construct is the Button1_Clickevent This isillustrated here:
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.ClickDim MediaPlayer As New WMPLib.WindowsMediaPlayerMediaPlayer.openPlayer(My.Computer.FileSystem.SpecialDirectories.MyMusic & _
“\” & DataGridView1.SelectedCells.Item(0).Value)End Sub
From this example, you can see that it is pretty simple to play one of the provided wma files It is assimple as creating an instance of the WMPLib.WindowsMediaPlayerobject and using the openPlayer
method, which takes as a parameter the location of the file to play In this case, you are again using the
SpecialDirectoriesproperty The nice thing about using this property is that it could be more difficult to find the user’s My Music folder due to the username changing the actual location of the filesthat the application is looking for, but using the Mynamespace allows it to figure out the exact location ofthe items When built and run, the application provides a list of available music files and allows you toeasily select one for playing in the Media Player This is illustrated in Figure 9-12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 10Figure 9-12
Though it would have been really cool if it were possible to play these types of files using the Audio
property from the My.Computernamespace, it is still possible to use the My.Computer.Audiospace for playing wav files and system sounds
name-To play a system sound, you use the following construct:
My.Form.Form1
To get at other forms, you simply change the namespace so that the name of the form that you are trying
to access follows the Formkeyword in the namespace construction
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 11The My.Resourcesnamespace is a tremendously easy way of getting at the resources stored in yourapplication If you open up the MyResources.resxfile from the My Projects folder in your solution,you can easily create as many resources as you wish As an example, I created a single Stringresourcetitled MyResourceStringand gave it a value of St Louis Rams
To access the resources that you create, you use the simple reference as shown here:
My.Resources.MyResourceString.ToString()
Using IntelliSense, you will find all of your created resources listed after you type the period after the
My.Resourcesstring
My.User
The My.Usernamespace allows you to work with the IPrincipalinterface You can use the My.User
namespace to figure out if the user is authenticated or not, what the user’s name is, and more Forinstance, if you have a login form in your application, you could allow access to a particular form withcode similar to the following:
If (Not My.User.IsInRole(“Administrators”)) Then
‘ Code hereEnd If
You can also just as easily get at the user’s name with the following:
My.User.Identity.Name
As well, you can check if the user is authenticated by using:
If My.User.Identity.IsAuthenticated Then
‘ Code hereEnd If
My.WebServices
When not using the My.WebServicesnamespace, you access your Web Services references in a lengthiermanner The first step in either case is to make a Web reference to some remote XML Web service in yoursolution These references will then appear in the Web References folder in Solution Explorer in VisualStudio 2005 Before the introduction of the Mynamespace, you would have accessed the values that theWeb reference exposed in the following manner:
Dim ws As New ReutersStocks.GetStockDetails
Trang 12Summar yThe introduction of namespaces with the NET Framework provides a powerful tool that helps toabstract the logical capabilities from their physical implementation While there are differences in thesyntax of referencing objects from a namespace and referencing the same object from a COM-style component implementation, there are several similarities This chapter introduced namespaces and theirhierarchical structure, and demonstrated
❑ That namespace hierarchies are not related to class hierarchies
❑ How to review and add references to a project
❑ How to import and alias namespaces at the module level
❑ How to create custom namespaces
❑ How to use the new MynamespaceNamespaces play an important role in enterprise software development The fact that namespaces allowyou to separate the implementation of related functional objects, while retaining the ability to groupthese objects, improves the overall maintainability of your code Everyone who has ever worked on alarge project has been put in the situation where a fix to a component has been delayed because of thepotential impact on other components in the same project Regardless of the logical separation of components in the same project, developers who took part in the development process worried abouttesting With totally separate implementations for related components, it is not only possible to alleviatethis concern but also easier than ever before for a team of developers to work on different parts of thesame project
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 13Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 14Exception Handling and
Debugging
All professional-grade programs need to handle unexpected conditions In programming languagesbefore Microsoft NET, this was often called error handling Unexpected conditions generated errorcodes, which were trapped by programming logic that took appropriate action
The common language runtime in NET does not generate error codes When an unexpected condition occurs, the CLR creates a special object called an exception This object contains properties and methods that describe the unexpected condition in detail and communicate variousitems of useful information about what went wrong
Because NET deals with exceptions instead of errors, the term “error handling” is seldom used
in the NET world Instead, now refer to exception handling This term refers to the techniques used in NET to detect exceptions and take appropriate action
In this chapter, we will cover how exception handling works in Visual Basic NET (VB.NET) Thereare many improvements over pre-.NET versions of Visual Basic This chapter will discuss the common language runtime (CLR) exception handler in detail and the programming methods thatare most efficient in catching errors Specifically, it will discuss:
❑ A brief review of error handling in Visual Basic 6 (VB6)
❑ The general principles behind exception handling
❑ The Try Catch Finallystructure, the Exit Trystatement, and nested Try
structures
❑ The exception object’s methods and propertiesSimpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 15❑ Exception handling between managed and unmanaged code, and how VB.NET assists you inthat area
❑ Capabilities in Visual Studio NET to work with exceptions
❑ Error and trace logging and how you can use these methods to obtain feedback on how yourprogram is working
You’ll begin with a quick review of error handling in previous versions of Visual Basic to use as a reference point Then you will look at the new ways of handling exceptions in NET
A Brief Review of Error Handling in VB6
For compatibility, Visual Basic NET still supports the old-style syntax for error handling that was used
in Visual Basic 6 and earlier versions That means you can still use the syntax presented in this review.However, it is strongly recommended that you avoid using this old-style syntax in favor of the exceptionhandling features that are native to NET
The old-style syntax in VB6 was handed down from DOS versions of BASIC The On Errorconstructwas created in an era when line labels and GoTostatements were commonly used Such error handling isdifficult to use and has limited functionality compared to more modern alternatives
In VB6, a typical routine with error handling code looks like this:
Private Function OpenFile(sFileName As String) As Boolean
On Error GoTo ErrHandler:
Open sFileName For Random As #1
OpenFile = True
Exit Sub
ErrHandler:
Select Case Err.Number
Case 53 ‘ File not foundMessageBox.Show “File not found”
Case ElseMessageBox.Show “Other error”
it looks at the error number to see what to do The error number is available as a property of the Err
object, which is a globally available object that holds error information in VB6
If the error handler can take care of the error without breaking execution, it can resume execution withthe line of code that generated the error ( Resume) or the one after that ( Resume Next) or at a particularlocation ( Resume {LineLabel})
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 16This structure becomes more complex if the error handling needs to vary in the routine Multiple OnError GoTostatements must be used to send errors to various error handlers, like this:
Private Function OpenFile(sFileName As String) As Boolean
On Error GoTo ErrHandler1
‘ Do calculations hereDim i As Integer
i = Len(sFileName)Dim j As Integer
j = 100 \ i
On Error GoTo ErrHandler2Open sFileName For Random As #1OpenFile = True
Exit Function
ErrHandler1:
Select Case Err.NumberCase 6 ‘ OverflowMessageBox.Show “Overflow”
Case ElseMessageBox.Show “Other error”
End Select
OpenFile = FalseExit Function
ErrHandler2:
Select Case Err.NumberCase 53 ‘ File not foundMessageBox.Show “File not found”
Case ElseMessageBox.Show “Other error”
End SelectOpenFile = False
End Function
With this type of error handling, it is easy to get confused about what should happen under various conditions You must change the error handling pointer as necessary or errors will be incorrectly processed There is very little information available about the error during the process, except for theerror number You can’t tell, for example, the line number on which the error was generated without single-stepping through the code
Such logic can rapidly become convoluted and unmanageable There’s a much better way to manage
errors in VB.NET, called structured exception handling The rest of this chapter will discuss this new way
to work with code errors, and you will use the term structured exception handling throughout, exceptfor the small sections that discuss compatibility with older error-handling techniques
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 17Exceptions in NET
.NET implements a systemwide, comprehensive approach to exception handling As noted in the chapterintroduction, the concept of an error is expanded to exceptions, which are objects that contain a set ofinformation relevant to the error Such an object is an instance of a class that derives from a class named
System.Exception
Important Properties and Methods of an Exception
The Exceptionclass has properties that contain useful information about the exception
Property Description
HelpLink A string indicating the link to help for this exception
InnerException Returns the exceptionobject reference to an inner (nested)
StackTrace A read-only property that holds the stack trace as a text
string The stack trace is a list of the pending method calls
at the point that the exception was detected That is,
if MethodAcalled MethodB, and an exception occurred in
MethodB, the stack trace would contain both MethodA
and MethodB
TargetSite A read-only string property that holds the method that
threw the exception
The two most important methods of the Exceptionclass are:
Method Description
GetBaseException Returns the first exception in the chain
ToString Returns the error string, which might include as much
information as the error message, the inner exceptions, andthe stack trace, depending on the error
You will see these properties and methods used in the code examples given later, once you have coveredthe syntax for detecting and handling exceptions
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 18How Exceptions Differ from the Err Object in VB6
Because an exception contains all of the information needed about an error, structured exception handlingdoes not use error numbers and the Errobject The exception object contains all the relevant informationabout the error
However, where there is only one global Errobject in VB6, there are many types of exception objects inVB.NET For example, if a divide by zero is done in code, then an OverflowExceptionis generated Thereare several dozen types of exception classes in VB.NET, and in addition to using the ones that are available
in the NET Framework, you can inherit from a class called ApplicationExceptionand then create yourown exception classes (see Chapter 6 for a discussion of inheritance)
In NET, all exceptions inherit from System.Exception Special-purpose exception classes can be found
in many namespaces The following table lists four representative examples of the classes that extend
Exception:
Namespace Class Description
System InvalidOperationException Generated when a call to an object
method is inappropriate because of theobject’s state
System OutOfMemoryException Results when there is not enough
memory to carry out an operation
System.XML XmlException Often caused by an attempt to read
invalid XML
System.Data DataException Represents errors in ADO.NET
components
There are literally dozens of exception classes scattered throughout the NET Framework namespaces It
is common for an exception class to reside in a namespace with the classes that commonly generate theexception For example, the DataExceptionclass is in System.Data, with the ADO.NET componentsthat often generate a DataExceptioninstance
Having many types of exceptions in VB.NET enables different types of conditions to be trapped withdifferent exception handlers This is a major advance over VB6 The syntax to do that is discussed next
Str uctured-Exception-Handling Keywords in VB.NET
Structured exception handling depends on several new keywords in VB.NET They are:
❑ Try— Begin a section of code in which an exception might be generated from a code error Thissection of code is often called a Tryblock In some respects, this would be the equivalent of an
On Errorstatement in VB6 However, unlike an On Errorstatement, a Trystatement does notindicate where a trapped exception should be routed Instead, the exception is automaticallySimpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 19❑ Catch— Begin an exception handler for a type of exception One or more Catchcode blocks comeafter a Tryblock, with each Catchblock catching a different type of exception When an exception
is encountered in the Tryblock, the first Catch block that matches that type of exception willreceive control
ACatchstatement is analogous to the line label used in a VB6 On Errorstatement, but the ability to route different types of exceptions to different Catchstatements is a radical improvement over VB6
❑ Finally— Contains code that runs when the Tryblock finishes normally, or if a Catch
block receives control and then finishes That is, the code in the Finallyblock always runs,regardless of whether an exception was detected Typically, the Finallyblock is used to close
or dispose of any resources, such as database connections, that might have been left unresolved
by the code that had a problem There is no equivalent of a Finallyin VB6
❑ Throw— Generate an exception This is similar to Err.Raisein VB6 It’s usually done in a
Catchblock when the exception should be kicked back to a calling routine or in a routine thathas itself detected an error such as a bad argument passed in
The Try, Catch, and Finally Keywords
Here is an example showing some typical simple structured exception handling code in VB.NET In thiscase, the most likely source of an error is the iItemsargument If it has a value of zero, this would lead
to dividing by zero, which would generate an exception
First, create a Windows Application in Visual Basic 2005, and place a button on the default Form1created
in the project In the button’s click event, place the following two lines of code:
Dim sngAvg As SinglesngAvg = GetAverage(0, 100)
Then put the following function in the form’s code:
Private Function GetAverage(iItems As Integer, iTotal As Integer) as Single
‘ Code that might throw an exception is wrapped in a Try blockTry
Dim sngAverage As Single
‘ This will cause an exception to be thrown if iItems = 0sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no errorMessageBox.Show(“Calculation successful”)
Return sngAverage
Catch excGeneric As Exception
‘ If the calculation failed, you get hereMessageBox.Show(“Calculation unsuccessful - exception caught”)Return 0
End Try
End Function
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 20In this code, you are trapping all the exceptions with a single generic exception type, and you don’t have any Finallylogic Run the program, and press the button You will be able to follow the sequencebetter if you place a breakpoint at the top of the GetAveragefunction and step through the lines.Here is a more complex example that traps the divide-by-zero exception explicitly This second version
of the GetAveragefunction (notice that the name is GetAverage2) also includes a Finallyblock:
Private Function GetAverage2(iItems As Integer, iTotal As Integer) as Single
‘ Code that might throw an exception is wrapped in a Try blockTry
Dim sngAverage As Single
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try blockMessageBox.Show(“Calculation generated DivideByZero Exception”)Return 0
Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
MessageBox.Show(“Calculation failed - generic exception caught”)Return 0
Finally
‘ Code in the Finally block will always run
MessageBox.Show(“You always get here, with or without an error”)End Try
End Function
In this code, there are two Catchblocks for different types of exceptions If an exception is generated,.NET will go down the Catchblocks looking for a matching exception type That means the Catch
blocks should be arranged with specific types first and more generic types later
Place the code for GetAverage2in the form, and place another button on Form1 In the Clickevent forthe second button, place the code:
Dim sngAvg As SinglesngAvg = GetAverage2(0, 100)
Run the program again and press the second button As before, it’s easier to follow if you set a breakpointearly in the code and then step through the code line by line
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 21The Throw Keyword
Sometimes a Catchblock is unable to handle an error Some exceptions are so unexpected that theyshould be “sent back up the line” to the calling code, so that the problem can be promoted to code thatcan decide what to do with it AThrowstatement is used for that purpose
AThrowstatement, like an Err.Raise, ends execution of the exception handler — that is, no more code in the Catchblock after the Throwstatement is executed However, Throwdoes not prevent code
in the Finallyblock from running That code still runs before the exception is kicked back to the callingroutine
You can see the Throwstatement in action by changing the earlier code for GetAverage2to look like this:
Private Function GetAverage3(iItems As Integer, iTotal as Integer) as Single
‘ Code that might throw an exception is wrapped in a Try blockTry
Dim sngAverage As Single
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try block
MessageBox.Show(“Calculation generated DivideByZero Exception”)
Throw excDivideByZeroMessageBox.Show(“More logic after the throw – never executed”)
Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
MessageBox.Show(“Calculation failed - generic exception caught”)
Throw excGenericFinally
‘ Code in the Finally block will always run, even if
‘ an exception was thrown in a Catch block
MessageBox.Show(“You always get here, with or without an error”)End Try
MessageBox.Show(“Back in the click event after an error”)Finally
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 22Throwing a New Exception
Throwcan also be used with exceptions that are created on the fly For example, you might like your earlier function to generate an ArgumentException, since you can consider a value of iItemsof zero
to be an invalid value for that argument
In such a case, a new exception must be instantiated The constructor allows you to place your own custom message into the exception To show how this is done, let’s change the aforementioned example
to throw your own exception instead of the one caught in the Catchblock
Private Function GetAverage4(iItems As Integer, iTotal as Integer) as Single
If iItems = 0 ThenDim excOurOwnException As New _ArgumentException(“Number of items cannot be zero”)
Throw excOurOwnException End If
‘ Code that might throw an exception is wrapped in a Try block
TryDim sngAverage As Single
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try block
MessageBox.Show(“Calculation generated DivideByZero Exception”)Throw excDivideByZero
MessageBox.Show(“More logic after the thrown - never executed”)Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
MessageBox.Show(“Calculation failed - generic exception caught”)Throw excGeneric
Finally
‘ Code in the Finally block will always run, even if
‘ an exception was thrown in a Catch block
MessageBox.Show(“You always get here, with or without an error”)End Try
End Function
This code can be called from a button with similar code for calling GetAverage3 Just change the name
of the function called to GetAverage4.This technique is particularly well suited to dealing with problems detected in property procedures.Property Setprocedures often do checking to make sure the property is about to be assigned a validvalue If not, throwing a new ArgumentException(instead of assigning the property value) is a goodSimpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 23The Exit Try Statement
The Exit Trystatement will, under a given circumstance, break out of the Tryor Catchblock and continue at the Finallyblock In the following example, you are going to exit a Catchblock if the value
of iItemsis 0, because you know that your error was caused by that problem
Private Function GetAverage5(iItems As Integer, iTotal as Integer) As Single
‘ Code that might throw an exception is wrapped in a Try block
TryDim sngAverage As Single
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try block
If iItems = 0 ThenReturn 0Exit TryElse
MessageBox.Show(“Error not caused by iItems”)End If
Throw excDivideByZeroMessageBox.Show(“More logic after the thrown - never executed”)
Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
MessageBox.Show(“Calculation failed - generic exception caught”)Throw excGeneric
Finally
‘ Code in the Finally block will always run, even if
‘ an exception was thrown in a Catch block
MessageBox.Show(“You always get here, with or without an error”)End Try
MessageBox.Show(“Error not caused by iItems”)End If
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 24Now, if the overflow exception is caused by something other than division by zero, you’ll get a messagebox displaying Error not caused by iItems.
Nested Try Structures
In some cases, particular lines in a Tryblock may need special exception processing Also, errors canoccur within the Catchportion of the Trystructures and can cause further exceptions to be thrown Forboth of these scenarios, nested Trystructures are available You can alter the example under the section
“The Throw Keyword” to demonstrate the following code:
Private Function GetAverage6(iItems As Integer, iTotal as Integer) As Single
‘ Code that might throw an exception is wrapped in a Try block
TryDim sngAverage As Single
‘ Do something for performance testing
TryLogEvent(“GetAverage”)Catch exc As ExceptionMessageBox.Show(“Logging function unavailable”)End Try
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try block
MessageBox.Show(“Error not divide by 0”)Throw excDivideByZero
MessageBox.Show(“More logic after the thrown - never executed”)Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
MessageBox.Show(“Calculation failed - generic exception caught”)Throw excGeneric
Finally
‘ Code in the Finally block will always run, even if
‘ an exception was thrown in a Catch block
MessageBox.Show(“You always get here, with or without an error”)End Try
End Function
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 25In this example, you are assuming that a function exists to log an event This function would typically be in
a common library, and might log the event in various ways We will actually discuss logging of exceptions
in detail later in the chapter, but a simple LogEventfunction might look like this:
Public Function LogEvent(ByVal sEvent As String)
FileOpen(1, “logfile.txt”, OpenMode.Append)Print(1, DateTime.Now & “-” & sEvent & vbCrLf)FileClose(1)
block exists
Using Exception Properties
The earlier examples have displayed hard-coded messages into message boxes, and this is obviously not
a good technique for production applications Instead, a message box describing an exception shouldgive as much information as possible concerning the problem To do this, various properties of theexception can be used
The most brutal way to get information about an exception is to use the ToStringmethod of the exception Suppose that you modify the earlier example of GetAverage2to change the displayed information about the exception like this:
Private Function GetAverage2(ByVal iItems As Integer, ByVal iTotal As Integer) _
As Single
‘ Code that might throw an exception is wrapped in a Try block
TryDim sngAverage As Single
‘ This will cause an exception to be thrown
sngAverage = CSng(iTotal \ iItems)
‘ This only executes if the line above generated no error
MessageBox.Show(“Calculation successful”)Return sngAverage
Catch excDivideByZero As DivideByZeroException
‘ You’ll get here with an DivideByZeroException in the Try block
MessageBox.Show(excDivideByZero.ToString)Throw excDivideByZero
MessageBox.Show(“More logic after the thrown - never executed”)
Catch excGeneric As Exception
‘ You’ll get here when any exception is thrown and not caught in
‘ a previous Catch block
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 26MessageBox.Show(“Calculation failed - generic exception caught”)Throw excGeneric
Finally
‘ Code in the Finally block will always run, even if
‘ an exception was thrown in a Catch block
MessageBox.Show(“You always get here, with or without an error”)End Try
End Function
When the function is accessed with iItems= 0, a message box similar to the one in Figure 10-1 will bedisplayed
Figure 10-1
The Message Property
The message in the aforementioned box is helpful to a developer, because it contains a lot of information.But it’s not something you would typically want a user to see Instead, the user normally needs to see ashort description of the problem, and that is supplied by the Messageproperty
If the previous code is changed so that the Messageproperty is used instead of ToString, then the message box will change to look something like Figure 10-2
The InnerException and TargetSite Properties
The InnerExceptionproperty is used to store an exception trail This comes in handy when multipleexceptions occur It’s quite common for an exception to occur that sets up circumstances whereby furtherexceptions are raised As exceptions occur in a sequence, you can choose to stack your exceptions forlater reference by use of the InnerExceptionproperty of your Exceptionobject As each exceptionjoins the stack, the previous Exceptionobject becomes the inner exception in the stack
Figure 10-2Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 27For simplicity, you’ll start a new code sample, with just a subroutine that generates its own exception.You’ll include code to add a reference to an InnerExceptionobject to the exception you are generatingwith the Throwmethod.
Your example will also include a message box to show what’s stored in the exception’s TargetSite
property As you’ll see in the results, TargetSitewill contain the name of the routine generating theexception, in this case HandlerExample Here’s the code:
Sub HandlerExample()
Dim intX As IntegerDim intY As IntegerDim intZ As IntegerintY = 0
intX = 5
‘ First Required Error Statement
Try
‘ Cause a “Divide by Zero”
intZ = CType((intX \ intY), Integer)
‘ Catch the error
Catch objA As System.DivideByZeroExceptionTry
Throw (New Exception(“0 as divisor”, objA))Catch objB As Exception
Messagebox.Show(objB.Message)Messagebox.Show(objB.InnerException.Message)Messagebox.Show(objB.TargetSite.Name)End Try
CatchMessagebox.Show(“Caught any other errors”)Finally
Messagebox.Show(Str(intZ))End Try
End Sub
As before, you catch the divide-by-zero error in the first Catchblock, and the exception is stored in objA
so that you can reference its properties later
You throw a new exception with a more general message ( “0 as divisor”) that is easier to interpret,and you build up your stack by appending objAas the InnerExceptionobject using an overloadedconstructor for the Exception object:
Throw (New Exception(“0 as divisor”, objA))
You catch your newly thrown exception in another Catchstatement Note how it does not catch a specifictype of error:
Catch objB As Exception
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 28Then you display three message boxes:
Messagebox.Show(objB.Message)Messagebox.Show(objB.InnerException.Message)Messagebox.Show(objB.TargetSite.Name)
The message box that is produced by your custom error, which is held in the objBvariable, is shown inFigure 10-3
Figure 10-3
The InnerExceptionproperty holds the exception object that was generated first The Messageproperty
of the InnerExceptionis shown in Figure 10-4
Figure 10-4
As mentioned earlier, the TargetSiteproperty gives you the name of the method that threw yourexception This information comes in handy when troubleshooting and could be integrated into the error message so that the end user could report the method name back to you Figure 10-5 shows a message box displaying the TargetSitefrom the previous example
Figure 10-5Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 29Source and StackTrace
The Sourceand StackTraceproperties provide the user with information regarding where the erroroccurred This supplemental information can be invaluable for the user to pass on to the troubleshooter
in order to help get errors resolved more quickly The following example uses these two properties andshows the feedback when the error occurs:
Sub HandlerExample2()
Dim intX As IntegerDim intY As IntegerDim intZ As IntegerintY = 0
intX = 5
‘ First Required Error Statement
Try
‘ Cause a “Divide by Zero”
intZ = CType((intX \ intY), Integer)
‘ Catch the error
Catch objA As System.DivideByZeroException
objA.Source = “HandlerExample2”
Messagebox.Show(“Error Occurred at :” & _objA.Source & objA.StackTrace)
FinallyMessagebox.Show(Str(intZ))End Try
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 30Sub HandlerExample3()Dim intX As IntegerDim intY As IntegerDim intZ As IntegerintY = 0
intX = 5
‘ First Required Error Statement
Try
‘ Cause a “Divide by Zero”
intZ = CType((intX \ intY), Integer)
‘ Catch the error
Catch objA As System.DivideByZeroException
TryThrow (New Exception(“0 as divisor”, objA))Catch objB As Exception
TryThrow (New Exception(“New error”, objB))Catch objC As Exception
Messagebox.Show(objC.GetBaseException.Message)End Try
End Try
FinallyMessagebox.Show(Str(intZ))End Try
End Sub
The InnerExceptionproperty provides the information that the GetBaseExceptionmethod needs,
so as your example executes the Throwstatements, it sets up the InnerExceptionproperty The purpose of the GetBaseExceptionmethod is to provide the properties of the initial exception in thechain that was produced Hence, objC.GetBaseException.Messagereturns the Messageproperty
of the original OverflowExceptionmessage even though you’ve thrown multiple errors since the original error occurred:
Messagebox.Show(objC.GetBaseException.Message)
To put it another way, the code traverses back to the exception caught as objAand displays the samemessage as the objA.Messageproperty would, as shown in Figure 10-7
Figure 10-7Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 31The HelpLinkproperty gets or sets the help link for a specific Exceptionobject It can be set to anystring value, but is typically set to a URL If you create your own exception in code, you might want toset HelpLinkto some URL describing the error in more detail Then the code that catches the exceptioncan go to that link You could create and throw your own custom application exception with code likethe following:
Dim exc As New ApplicationException(“A short description of the problem”)
exc.HelpLink = “http://mysite.com/somehtmlfile.htm”
Throw exc
When trapping an exception, the HelpLinkcan be used to launch a viewer so that the user can see thedetails about the problem The following example shows this in action, using the built-in Explorer inWindows:
‘ Catch the error
Catch objA As System.Exception
Shell(“explorer.exe “ & objA.HelpLink)
End Try
End Sub
This results in launching Internet Explorer to show the page specified by the URL
Most exceptions thrown by the CLR or the NET Framework’s classes have a blank HelpLinkproperty.You should only count on using HelpLinkif you have previously set it to a URL (or some other type oflink information) yourself
Interoperability with VB6-Style
Catchblock just as a normal exception would be Here’s a code example to illustrate
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 32First, create a subroutine that creates an error with Err.Raise, like this:
Private Sub RaiseErrorWithErrRaise()Err.Raise(53) ‘ indicates File Not FoundEnd Sub
Then call this routine from a button’s click event, with the call inside a Try Catchblock, like this:
Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.ClickTrºy
RaiseErrorWithErrRaise()Catch ex As ExceptionMessageBox.Show(ex.Message)End Try
While error logging is very important, you only want to use it to trap specific levels of errors because itcarries overhead and can reduce the performance of your application You want to only log errors thatwill be critical to your application integrity — for instance, an error that would cause the data that theapplication is working with to become invalid
There are three main approaches to error logging:
❑ Write error information in a text file or flat file located in a strategic location
❑ Write error information to a central database
❑ Write error information to the Event Log that is available on the Windows OS (NT, 2000, XP, and2003) The NET Framework includes a component that can be used to write and read from theSystem, Application, and Security Logs on any given machine
The type of logging you choose depends on the categories of errors you wish to trap and the types ofmachines you will run your application on If you choose to write to the event log, you need to categorizethe errors and write them in the appropriate log file Resource-, hardware-, and system-level errors fit bestinto the System Event Log Data access errors fit best into the Application Event Log Permission errors fitbest into the Security Event Log
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 33The Event Log
There are three Event Logs available: the System, Application, and Security Logs Events in these logscan be viewed using the Event Viewer, which is accessed from the Control Panel Access AdministrativeTools and then select the Event Viewer subsection to view events Typically, your applications would use the Application event log
Event logging is available in your program through an Event Log component It can both read and write
to all of the available logs on a machine The EventLogcomponent is part of the System.Diagnostics
namespace The component allows adding and removing custom Event Logs, reading and writing toand from the standard Windows Event Logs, and creating customized Event Log entries
Event Logs can get full, as they have a limited amount of space, so you only want to write critical information to your Event Logs You can customize each of your system Event Log’s properties bychanging the log size and determining how the system will handle events that occur when the log is full You can configure the log to overwrite data when it is full or overwrite all events older than a givennumber of days It is important to remember that the Event Log that is written to is based on where thecode is running from, so that if there are many tiers, you can locate the proper Event Log information toresearch the error further
There are five types of Event Log entries you can make These five types are divided into event typeentries and audit type entries
Event type entries are:
❑ Information— Added when events such as a service starting or stopping occurs
❑ Warning— Occurs when a noncritical event occurs that might cause future problems, such asdisk space getting low
❑ Error— Should be logged when something occurs that will prevent normal processing, such as
a startup service not being able to startAudit type entries will usually go into the Security Log and can be either:
❑ Success audit— For example, a success audit might be a successful login through an tion to an SQL Server
applica-❑ Failure audit— A failure audit might come in handy if a user doesn’t have access to create anoutput file on a certain file system
Event logs are not available on Windows 98 or Windows ME, even though NET supports these systems If you expect to support these operating systems on client machines, you will not be able to use the built-in Event Log classes shown here.
Logging on these systems will require building your own custom log You may want your logging component to check the OS version and decide whether to log to an Event Log or a custom log.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 34If you don’t specify the type of Event Log entry, an information type entry is generated.
Each entry in an Event Log has a Sourceproperty The Sourceproperty is required and is a programmer-defined string that is assigned to an event that helps categorize the events in a log A new
Sourcemust be defined prior to being used in an entry in an Event Log The SourceExistsmethod isused to determine if a particular source already exists on the given computer We recommend that youuse a string that is relevant to where the error originated, such as the component name Packaged software often uses the software name as the Source in the Application Log This helps group errors that occur by specific software package
The EventLogcomponent is in the System.Diagnosticsnamespace To use it conveniently, you need
to include an Imports System.Diagnosticsstatement in the declarations section of your code
The most common events, methods, and properties for the EventLogcomponent are listed anddescribed in the following tables
Events, Methods, and Properties
The following table describes the relevant event
Event Description
EntryWritten Generated when an event is written to a log
The following table describes the relevant methods
Methods Description
CreateEventSource Creates an event source in the specified log
DeleteEventSource Deletes an event source and associated entries
WriteEntry Writes a string to a specified log
Exists Can be used to determine if a specific event log exists
SourceExists Used to determine if a specific source exists in a log
GetEventLogs Retrieves a list of all event logs on a particular computer
Delete Deletes an entire Event Log — use this method with care
Certain security rights must be obtained in order to manipulate Event Logs.
Ordinary programs can read all of the Event Logs and write to the Application Event Log Special privileges, on the administrator level, are required to perform tasks such as clearing and deleting Event Logs Your application should not normally need to do these tasks, or to write to any log besides the Application Event Log.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 35The following table describes the relevant properties.
Properties Description
Source Specifies the source of the entry to be written
Log Used to specify a log to write to The three logs are System,
Application, and Security The System Log is the default ifnot specified
Here is an example that illustrates some of these methods and properties:
Sub LoggingExample1()
Dim objLog As New EventLog()Dim objLogEntryType As EventLogEntryTypeTry
Throw (New EntryPointNotFoundException())Catch objA As System.EntryPointNotFoundException
If Not objLog.SourceExists(“Example”) ThenobjLog.CreateEventSource(“Example”, “System”)End If
objLog.Source = “Example”
objLog.Log = “System”
objLogEntryType = EventLogEntryType.InformationobjLog.WriteEntry(“Error: “ & objA.Message, objLogEntryType)End Try
End Sub
You have declared two variables — one to instantiate your log and one to hold your entry’s type information Note that you need to check for the existence of a source prior to creating it These two lines
of code accomplish this:
If Not objLog.SourceExists(“Example”) Then
objLog.CreateEventSource(“Example”, “System”)
Once you have verified or created your source, you can set the Sourceproperty of the EventLog
object, set the Logproperty to specify which log you want to write to, and EventLogEntryTypeto
Information(other choices are Warning, Error, SuccessAudit, and FailureAudit) If you attempt towrite to a source that does not exist in a specific log, you will get an error After you have set these threeproperties of the EventLogobject, you can then write your entry In this example, you concatenated theword Errorwith the actual exception’s Messageproperty to form the string to write to the log:
objLog.Source = “Example”
objLog.Log = “System”
objLogEntryType = EventLogEntryType.Information
objLog.WriteEntry(“Error: “ & objA.Message, objLogEntryType)
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 36Writing to Trace Files
As an alternative for platforms that don’t support event logging, or if you can’t get direct access to theEvent Log, you can write your debugging and error information to trace files A trace file is a text-basedfile that you generate in your program to track detailed information about an error condition Trace filesare also a good way to supplement your event logging if you wish to track detailed information thatwould potentially fill the Event Log
A more detailed explanation of the variety of trace tools and uses in debugging follows in “AnalyzingProblems and Measuring Performance via the Trace Class,” but you will cover some of the techniquesfor using the StreamWriterinterface in your development of a trace file in this section
The concepts involved in writing to text files include setting up streamwriters and debug listeners The
StreamWriterinterface is handled through the System.IOnamespace and allows you to interface with the files in the file system on a given machine The Debugclass interfaces with these output objectsthrough listener objects The job of any listener object is to collect, store up, and send the stored output totext files, logs, and the Output window In your example, you will use the TextWriterTraceListener
interface
As you will see, the StreamWriterobject opens an output path to a text file, and by binding the
StreamWriterobject to a listener object you can direct debug output to a text file
Trace listeners are output targets and can be a TextWriteror an EventLog, or can send output to the default Output window (which is DefaultTraceListener) The TextWriterTraceListener
accommodates the WriteLinemethod of a Debuginterface by providing an output object that stores
up information to be flushed to the output stream, which you set up by the StreamWriterinterface.The following table lists some of the commonly used methods from the StreamWriterobject
Method Description
Close Closes the StreamWriter
Flush Flushes all content of the StreamWriterto the output file
designated upon creation of the StreamWriter
Write Writes byte output to the stream Optional parameters allow
designation of where in the stream (offset)
WriteLine Writes characters followed by a line terminator to the current
Trang 37Method Description
Assert Checks a condition and displays a message if False
Close Executes a flush on the output buffer and closes all listeners
Ignore message box
Flush Flushes the output buffer and writes it to the listeners
Write Writes bytes to the output buffer
WriteLine Writes characters followed by a line terminator to the output
buffer
WriteIf Writes bytes to the output buffer if a specific condition is
True
WriteLineIF Writes characters followed by a line terminator to the output
buffer if a specific condition is True
Sub LoggingExample2()
Dim objWriter As New _IO.StreamWriter(“C:\mytext.txt”, True)Debug.Listeners.Add(New TextWriterTraceListener(objWriter))Try
Throw (New EntryPointNotFoundException())Catch objA As System.EntryPointNotFoundExceptionDebug.WriteLine(objA.Message)
objWriter.Flush()objWriter.Close()objWriter = NothingEnd Try
You then assign your StreamWriterto a debug listener by using the Addmethod:
Debug.Listeners.Add(New TextWriterTraceListener (objWriter))
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 38In this example, you force an exception and catch it, writing the Messageproperty of the Exception
object (which is Entry point was not found.) to the debug buffer through the WriteLinemethod:
Debug.WriteLine(objA.Message)
You finally flush the listener buffer to the output file and free your resources
objWriter.Flush()objWriter.Close()objWriter = Nothing
Analyzing Problems and Measuring Performance via the Trace ClassThe trace tools in the NET Framework revolve around the Traceclass, which provides properties andmethods that help you trace the execution of your code By default, tracing is enabled in VB.NET, so notunlike your previous debug discussion, all you have to do is set up the output and utilize its capabilities.You can specify the detail level you want to perform for your tracing output by configuring trace switches.You will show an example of setting a trace switch shortly, but first you need to cover what a trace switchcan do and what the settings for trace switches mean
Trace switches can be either BooleanSwitchor TraceSwitch BooleanSwitchhas a value of either 0or
1and is used to determine if tracing is off or on, respectively, while TraceSwitchallows you to specify alevel of tracing based on five enumerated values You can manage a BooleanSwitchor TraceSwitchas
an environment variable Once a switch is established, you can create and initialize it in code and use itwith either trace or debug
ATraceSwitchcan have five enumerated levels that can be read as 0–4or checked with four propertiesprovided in the switch class interface The four properties return a Boolean value based on whether theswitch is set to a certain level or higher The five enumerated levels for TraceSwitchare as follows
Level Description
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 39The four properties are TraceError, TraceWarning, TraceInfo, and TraceVerbose For example, ifyour switch was set at number 2and you asked for the TraceErroror TraceWarningproperties, theywould return True, while the TraceInformationand TraceVerboseproperties would return False.
An environment variable is either managed via the command line or under My computer ➪ Properties ➪Advanced within the Environment Variables button
Within the Environment Variables button, you add a new Uservariable, giving it the SwitchNameand
Valuefor that switch
From the command line, type
Set _Switch_MySwitch = 0
The value on the left of the = symbol is the name of the switch, and the value on its right is either 0or 1
for a BooleanSwitchor 0–4for a TraceSwitch Note that there is a space between the word Setandthe leading underscore of _Switch Once you have typed this line, if you follow that by the plain SET
command at the command line, it will show your new switch as an environment variable, as shown inFigure 10-8
TryThrow (New EntryPointNotFoundException())Catch objA As System.EntryPointNotFoundExceptionTrace.WriteLineIf(objTraceSwitch.TraceVerbose, _
“First Trace “ & objA.Source)Trace.WriteLineIf(objTraceSwitch.TraceError, _
“Second Trace “ & objA.Message)End Try
End Sub
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 40You begin by assigning your switch to an existing registry entry and setting its level:
objTraceSwitch = New TraceSwitch(“ExampleSwitch”, “Test Trace Switch”)objTraceSwitch.Level = TraceLevel.Error
After you throw your exception, you first cause your trace output listener to catch the Sourceproperty
of your Exceptionobject based on whether the value of your switch is TraceVerboseor better:
Trace.WriteLineIf(objTraceSwitch.TraceVerbose, _
“First Trace “ & objA.Source)
Since the tracing level is set to Error, this line is skipped and you continue by writing a trace to theOutput window to include the message information if the level is set to Error:
Trace.WriteLineIf(objTraceSwitch.TraceError, _
“Second Trace “ & objA.Message)
As you can see in your Output window shown, you successfully wrote only the second trace line based
on the level being Erroron your trace switch, as can be seen in Figure 10-9
Figure 10-9
The other thing you want the ability to do is to determine the performance of your application Overall,your application might appear to be working fine, but it is always a good thing to be able to measure the performance of your application so that environment changes or degradation over time can be counteracted The basic concept here is to use conditional compilation so that you can turn on and off your performance-measuring code:
Sub TraceExample2()Dim connInfo As New Connection()Dim rstInfo As New Recordset()
#Const bTrace = 1Dim objWriter As New _IO.StreamWriter(IO.File.Open(“c:\mytext.txt”, IO.FileMode.OpenOrCreate))connInfo.ConnectionString = “Provider = sqloledb.1” & _
“;Persist Security Info = False;” & “Initial Catalog = Northwind;” & _
“DataSource = LocalServer”
connInfo.Open(connInfo.ConnectionString, “sa”)Trace.Listeners.Add(New TextWriterTraceListener(objWriter))
#If bTrace ThenTrace.WriteLine(“Begun db query at “ & now())
#End IfrstInfo.Open(“SELECT CompanyName, OrderID, “ & _
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com