1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional VB 2005 - 2006 phần 4 pps

110 136 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 110
Dung lượng 5,47 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 1

Figure 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 2

If 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 3

Property/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 4

Another 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 5

Figure 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 6

Version=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 7

Property 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 8

There 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 9

Now 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 10

Figure 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 11

The 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 12

Summar 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 13

Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com

Trang 14

Exception 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 16

This 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 17

Exceptions 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 18

How 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 20

In 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 21

The 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 22

Throwing 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 23

The 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 24

Now, 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 25

In 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 26

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

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 27

For 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 28

Then 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 29

Source 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 30

Sub 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 31

The 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 32

First, 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 33

The 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 34

If 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 35

The 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 36

Writing 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 37

Method 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 38

In 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 39

The 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 40

You 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

Ngày đăng: 12/08/2014, 23:23

TỪ KHÓA LIÊN QUAN