# Apply Your Knowledge

#### Exercises

##### 9.1 Creating a Custom Trace Switch

The TraceSwitch and BooleanSwitch classes are two built-in classes that provide trace switch functionalities. If you need different trace levels or different implementations of the Switch class, you can inherit from the Switch class and implement your own custom trace switch.

In this exercise, I show you how to create a custom trace switch. I will create a FactorialSwitch class that can be set with four values ( Negative [ -1 ], Off [ ], Overflow [ 1 ] and Both [ 2 ]) for the Factorial Calculator form. The class will have two properties, Negative and Overflow.

Estimated time : 25 minutes.

1. Launch Visual Studio .NET, Select File, New, Blank Solution and name the new solution 310C09Exercises .

2. Add a new Windows application project to the solution. Name the project Exercise9-1 .

3. Delete Form1.vb from the new project.

4. Follow the directions from Step By Step 9.1 to create a copy of the FactorialCalculator.vb form in this project.

5. Add a new class to the project. Name the class FactorialSwitch.vb and modify the class definition with the following code:

` Imports System Imports System.Diagnostics Public Enum FactorialSwitchLevel     Negative = -1     Off = 0     Overflow = 1     Both = 2 End Enum Public Class FactorialSwitch     Inherits Switch     Public Sub New(_     ByVal DisplayName As String, _      ByVal Description As String)         MyBase.New(DisplayName, Description)     End Sub     Public Property Negative() As Boolean         Get             ' Return true if the             ' SwitchSetting             ' is Negative or Both             If ((SwitchSetting = -1) Or _              (SwitchSetting = 2)) Then                 Return True             Else                 Negative = False             End If         End Get         Set(ByVal Value As Boolean)         End Set     End Property     Public Property Overflow() As Boolean         Get             ' Return true if the             ' SwitchSetting             ' is Overflow or Both             If ((SwitchSetting = 1) Or _              (SwitchSetting = 2)) Then                 Return True             Else                 Negative = False             End If         End Get         Set(ByVal Value As Boolean)         End Set     End Property End Class `
6. Open FactorialCalculator.vb in code view. Change the Click event handler of the btnCalculate control as follows :

` Private Sub btnCalculate_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles btnCalculate.Click     Dim facSwitch As FactorialSwitch = _      New FactorialSwitch("FactorialTrace", _      "Trace the factorial application")     Dim intNumber As Integer = _      Convert.ToInt32(txtNumber.Text)     If facSwitch.Negative Then         ' Make a debug assertion         Debug.Assert(intNumber >= 0, _         "Invalid value", _          "negative value in debug mode")     End If     Dim intFac As Integer = 1     Dim i As Integer     Try         For i = 2 To intNumber             intFac = intFac * i         Next     Catch ex As Exception         If facSwitch.Overflow Then             ' Write a debug message             ' if the condition is true             Debug.WriteLineIf(intFac < 1, _              "There was an overflow", _              "Factorial Program Debug")         End If     End Try     txtFactorial.Text = intFac.ToString() End Sub `
7. In the Solution Explorer, select Show All Files from the toolbar. Navigate to the bin folder. Right-click on this folder to select Add, Add New Item. Choose to create an XML file; name the XML file as Exercise9-1.exe.config.

8. In the XML editor, type the following configuration data in the XML file.

` <?xml version="1.0" encoding="utf-8" ?> <configuration>     <system.diagnostics>         <switches>             <add name="FactorialTrace" value="2" />         </switches>     </system.diagnostics> </configuration> `
9. Set the form as the startup form for the project and set the project as the startup project for the solution.

10. Run the project using the default Debug configuration. You will notice that the Negative assertion dialog box is displayed only if the switch is set with values 1 or 2 . Similarly, the Overflow message is displayed in the Output window only if the switch value is set to 1 or 2 .

The value set in the configuration file can be accessed through the SwitchSetting property of the Switch class. The Negative and Overflow properties of the FactorialSwitch class return True or False , depending on the value of the SwitchSetting property.

##### 9.2 Debugging SQL Server Stored Procedures Using Visual Basic .NET

You can perform step-by-step execution of SQL Server stored procedures in Visual Basic .NET. This exercise shows you how.

Estimated time : 30 minutes

1. Add a new Windows application project to the solution. Name the project Exercise9_2 .

2. Rename the Form1.vb form MostExpensiveProducts.vb . Switch to code view and change all occurrences of Form1 to MostExpensiveProducts .

3. Select Project, Properties from the main menu. Select Debugging under the Configuration Properties node in the left pane of the Property Pages window. Change the configuration to Active(Release). In the right pane, under the Debuggers node, choose the check box to enable SQL Server debugging, as shown in Figure 9.41.

##### Figure 9.41. You should enable SQL debugging in the Property pages dialog box to allow debugging of SQL Server stored procedures.

4. Drag a SqlDataAdapter component to the form from the Data tab of the toolbox. This activates the Data Adapter Configuration Wizard. Click Next. Select the Northwind database connection that you have already created in the earlier chapters or click the New Connection button to create a Northwind database connection. Click Next.

5. Choose the Use Existing Stored Procedures option in the Choose a Query Type page. Click Next. Select Ten Most Expensive Products from the Select combo box, as shown in Figure 9.42. Click Next and then click Finish. A SqlDataAdapter component and a SqlConnection component are created in the component tray.

##### Figure 9.42. The Bind commands to Existing Stored Procedures dialog box allows you to choose SQL stored procedures to bind to SqlCommand objects.

6. Select the SqlDataAdapter1 component, and then right-click and select Generate DataSet from the context menu. Select the New radio button and choose Ten Most Expensive Products (SqlDataAdapter1) from the checked list box. Click OK to create a DataSet11 component in the component tray.

7. Place a Button control ( btnGetProducts ) and a DataGrid control ( DataGrid1 ) on the form. Change the DataGrid control's DataSource property to DataSet11 and DataMember property to Ten Most Expensive Products .

8. Add the following code to the Click event of the Button control:

` Private Sub btnGetProducts_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles btnGetProducts.Click     SqlDataAdapter1.Fill(DataSet11) End Sub `
9. Insert a breakpoint in the Click event handler at the point of a call to the Fill() method of the sqlDataAdapter1 object.

10. Open Server Explorer. Open the Data Connections node and select the stored procedure Ten Most Expensive Products. You can find this stored procedure by drilling into the tree, starting with the Data Connections node, and then the node for the current connection, and then the Stored Procedures folder. Right-click the stored procedure and select Edit Stored Procedure. Insert a breakpoint in the starting code line of the stored procedure, as shown in Figure 9.43.

##### Figure 9.43. You can even insert a breakpoint in the SQL Server stored procedures.

11. Set the form as the startup object for the project. Run the project. Click the button. The program starts step-by-step execution as soon as it encounters the breakpoint in the Fill() method call line. Press F8. You are taken to the stored procedure code where you can perform step-by-step execution.

This exercise teaches you how to debug SQL Server stored procedures by using step-by-step execution. In Figure 9.43, notice the outline enclosing the SELECT statement. The outline encloses a single debugging step.

WARNING

Watching SQL Server Variables You can use various tools, such as the Watch and Locals windows, to keep track of the values of the variables defined in the stored procedures during step-by-step execution. These tools are very helpful when you are debugging complex stored procedures.

#### Review Questions

 1: For what do you use a test plan? A1: A test plan is a document that guides the process of testing. This document should clearly specify the different approaches to testing, the test cases, the validation criteria of the tests, and so on. 2: What is the purpose of the Assert() method in the Debug and Trace classes? A2: The Assert() method takes a condition as its first parameter and then displays an Assertion Failed dialog box if the condition evaluates to false . 3: What is the main purpose of TraceListener class? What classes implement TraceListener in the Framework Class Library? A3: TraceListener is an abstract class that provides functionality for receiving trace and debug messages. DefaultTraceListener , TextWriterTraceListener , and EventLogTraceListener are the three built-in classes that implement TraceListener . 4: What are the two built-in trace switches in the .NET Framework Class Library? A4: The two built-in trace switches in the .NET Framework Class Library are BooleanSwitch and TraceSwitch . 5: What is the main advantage of trace switches? A5: You can easily change the value of trace switches by editing the application configuration (XML) file, using any text editor. To make these changes take effect, you need not recompile the application; you just need to restart it. 6: What types of methods can be marked with the Conditional attribute? A6: Before you can apply the Conditional attribute to a method, the method should be a Sub rather than a Function. 7: What three commands can you use to step through code while debugging? A7: The three commands that allow you to step through code are Step Into (steps into each statement of the method called), Step Over ( performs the entire method call in one step), and Step Out (steps out of the method call). 8: What happens when you put a breakpoint in code? A8: When the debugger encounters a breakpoint in code, it pauses the execution of the application. The execution can be resumed via the stepping commands. 9: What are some of the different windows available for debugging? A9: Visual Studio .NET provides a variety of windows to ease the debugging process. Some of these windows are Me, Locals, Autos, Watch, Call Stack, and Breakpoints. 10: How can you attach the debugger to a running process in Visual Basic .NET? A10: To attach the debugger to a running process, open Visual Basic .NET, invoke the Processes dialog, select the process from the list of processes, and click the Attach button. 11: In order to verify that remote debugging is enabled on a system, what should you check? A11: You should verify that the remote machine has Machine Debug Manager ( mdm.exe ) running as a background process to enable debugging support. You should also verify that you are a member of the Debugger Users group in order to remotely access the machine for debugging. 12: How can you debug an already running COM+ (Enterprise Services) application? A12: To debug a COM+ library application, you must attach a debugger to the process in which the client application is running. On the other hand, to debug a COM+ server application, you must attach a debugger to the dllhost.exe process in which the COM+ server application is running.

#### Exam Questions

 1: Which of the following activities correctly defines a typical unit test? Locate and fix errors. Run the application with carefully planned test data and determine whether it works according to its specification. Run a module with carefully planned test data and determine whether it works according to its specification. Verify that a program module integrates well with other modules in an application. A1: C. A unit test involves running a module against carefully planned test data and checking whether it works according to its specification. Debugging is the process of locating and fixing errors. When you run a complete application against test data, you are performing system testing. Checking whether the modules integrate well is part of integration testing. 2: You are creating a .NET remoting object. You want to add code to the object to log error messages and warning messages. You want to log messages to both a log file and to the Windows application log but do not want a message to be duplicated . Which of the following code segments should you use? ` Dim fl As FileStream = _ New File.Create("RemObject.log") Dim el As EventLog = _ New EventLog("RemObject") Trace.WriteLine(fl, "Sample Message") Trace.WriteLine(el, "Sample Message") ` ` Trace.Listeners.Add(_ New EventLogListener("RemObject")) Trace.Listeners.Add(_ New TextFileTraceListeners(_ "RemObject.log")) Trace.WriteLine("Sample Message") Trace.WriteLine("Sample Message") ` ` Trace.Listeners.Add(_ New EventLogListener("RemObject")) Trace.Listeners.Add(_ New TextFileTraceListeners(_ "RemObject.log")) Trace.WriteLine("Sample Message") ` ` Dim el As EventLogTraceListener = _ New EventLogTraceListener("RemObject") Dim fl As TextFileTraceListeners = _ New TextFileTraceListeser("RemObject.log") el.WriteLine("Sample Message") fl.WriteLine("Sample Message") ` A2: C. To log messages to custom target locations, you need to add custom listeners to the Trace.Listeners collection. This eliminates choices A and D. In between B and C, C is correct because you want to log a message only once. 3: You are developing a Windows application that heavily uses SQL Server stored procedures. You are debugging a Windows form that calls the YTDSales stored procedure. The stored procedure uses a variable named @Sales. You want to see how the value of this variable changes as the code in the stored procedure executes. Which of the following options will allow you to do this? Use the SQL Server PRINT command to display the value of the @Sales variable at different places. Use Debug.Write statements to print the value of the @Sales variable. Use Trace.Write statements to print the value of the @Sales variable. Use the Locals window to monitor the value of @Sales as you step through the stored procedure. A3: D. You can use the Locals window to keep track of the values of the variables defined in the Stored Procedures during its step-by-step execution. 4: In your Visual Basic .NET program, you have the following lines of code: ` Dim MyTraceSwitch As TraceSwitch = _ New TraceSwitch(_ "SwitchOne", "The first switch") MyTraceSwitch.Level = TraceLevel.Info ` Which of the following expressions in your program would evaluate to false ? MyTraceSwitch.TraceInfo MyTraceSwitch.TraceWarning MyTraceSwitch.TraceError MyTraceSwitch.TraceVerbose A4: D. Setting the Level property of TraceSwitch to TraceLevel.Info allows it to capture all informational, warning, and error messages, but not the verbose messages. Thus, the TraceInfo , TraceWarning , and TraceError properties of the switch evaluate to True but the TraceVerbose property evaluates to False . 5: You are developing a retail Web site for selling ready-made garments. Your application has a collection of serviced components that executes the business logic. All the serviced components are marked with the Transaction(TransactionOption.Required) attribute. All the methods in the components are marked with the AutoComplete attribute. While testing the application, you find that inventory is not being updated properly. When you attempt to debug the application, a System.Runtime.InteropServices.COMException is thrown. The exception includes the following message: "The root transaction wanted to commit, but transaction aborted." You also find that this exception occurs only during the debugging session, and not when the components run outside of the debugger. You need to resolve this problem so that you can debug the application to find the problem with inventory updates. Which of the following options should you select to resolve this problem? Remove the AutoComplete attribute from each method. Within each method implementation, add calls to the ContextUtil.SetComplete() and ContextUtil.SetAbort() methods. Remove the AutoComplete attribute from each method. Within each method implementation, add calls to the ContextUtil.MyTransactionVote and ContextUtil.DeactivateOnReturn properties. Use the Component Services administrative tool. Access the Properties dialog box for My Computer and increase the transaction timeout duration. Change the implementation of each method in the serviced component by adding the following code segment: ` Try ' the business logic goes here Catch ex As Exception ' log any error messages here Finally ContextUtil.SetComplete() End Try ` A5: C. When you debug a program, the transaction might not complete in the set timeframe (the default is 60 seconds). In that case, the program will throw the given exception. Because you have a bunch of components here, instead of setting the transaction timeout value for each of them individually, you can set the transaction timeout property for the applications running the computer. 6: You are asked to implement tracing in an XML Web service such that the application should display both warning and error messages when the application is run by using the Debug configuration, but should display only error messages when it is run by using the Release configuration. Which of the following code segments best meets this requirement? ` Dim ts As TraceSwitch = _ New TraceSwitch("MySwitch", _ "Error and Warning Switch") #if DEBUG ts.Level = TraceLevel.Warning #else ts.Level = TraceLevel.Error #endif Trace.WriteLineIf(ts.TraceWarning, _ "Warning Message") Trace.WriteLineIf(ts.TraceError, _ "Error Message") ` ` Dim ts As TraceSwitch = _ New TraceSwitch("MySwitch", _ "Error and Warning Switch") #if DEBUG ts.Level = TraceLevel.Warning #else ts.Level = TraceLevel.Error #endif Debug.WriteLineIf(ts.TraceWarning, "Warning Message") Debug.WriteLineIf(ts.TraceError, _ "Error Message") ` ` Dim ts As TraceSwitch = _ New TraceSwitch("MySwitch", _ "Error and Warning Switch") #if TRACE ts.Level = TraceLevel.Warning #else ts.Level = TraceLevel.Error #endif Trace.WriteLineIf(ts.TraceWarning, "Warning Message") Trace.WriteLineIf(ts.TraceError, _ "Error Message") ` ` Dim ts As TraceSwitch = _ New TraceSwitch("MySwitch", _ "Error and Warning Switch") #if TRACE ts.Level = TraceLevel.Error #else ts.Level = TraceLevel.Warning #endif Trace.WriteLineIf(ts.TraceWarning, "Warning Message") Trace.WriteLineIf(ts.TraceError, _ "Error Message") ` A6: A. In answer A, for the Debug configuration where the DEBUG symbol is defined, the Level property of traceSwitch is set to TraceLevel.Warning . This causes both the TraceWarning and TraceError properties of this object to evaluate to True in the Debug configuration, causing both of the messages to be displayed. In the Release configuration, where only the TRACE symbol is defined, the Level property of traceSwitch is set to TraceLevel.Error . This causes the TraceWarning property to result in a False value and the TraceError property to return a True value, causing only the error messages to be displayed. 7: The configuration file of an XML Web service has the following contents: ` ` You are using the following statements to create switch objects in your code: ` Dim bs As BooleanSwitch = _ New BooleanSwitch(_ "BooleanSwitch", "Boolean Switch") Dim ts As TraceSwitch = _ New TraceSwitch(_ "TraceLevelSwitch", "Trace Switch") ` Which of the following options is correct regarding the values of these switch objects? The bs.Enabled property is set to false , and ts.Level is set to TraceLevel.Verbose . The bs.Enabled property is set to true , and ts.Level is set to TraceLevel.Verbose . The bs.Enabled property is set to false , and ts.Level is set to TraceLevel.Error . The bs.Enabled property is set to false , and ts.Level is set to TraceLevel.Info . A7: B. For BooleanSwitch , a value of corresponds to Off , and any nonzero value corresponds to On . For TraceSwitch any number greater than 4 is treated as Verbose . From the given values in the configuration file, the booleanSwitch object should have its Enabled property set as true , and the traceSwitch object should have its Level property set to TraceLevel.Verbose . 8: You are developing a Windows application. Your application's configuration files have the following code: ` ` You have written the following tracing code in your program: ` Dim ts As TraceSwitch = New TraceSwitch(_ "TraceLevelSwitch", _ "Trace the application") _ Private Sub Method1() Trace.WriteLineIf(ts.TraceError, "Message 1", "Message 2") End Sub Private Sub Method2() Trace.WriteLine("Message 3") End Sub Private Sub btnCalculate_Click(_ sender As Object, _ e As System.EventArgs e) _ Handles btnCalculate.Click If ts.TraceWarning Then Trace.WriteLine("Message 10") Method1() Else Trace.WriteLineIf(ts.TraceInfo, _ "Message 20") Method2() End If If ts.TraceError Then Trace.WriteLineIf(_ ts.TraceInfo, "Message 30") End If Trace.WriteLineIf(ts.TraceVerbose, _ "Message 40") End Sub ` What tracing output would be generated if you ran your program in Debug mode and clicked the btnCalculate button? ` Message 10 Message 1 Message 2 Message 30 ` ` Message 10 Message 2: Message 1 Message 30 ` ` Message 10 Message 2 Message 30 Message 40 ` ` Message 20 Message 3 Message 30 Message 40 ` A8: B. The XML file has 3 as the value for TraceLevelSwitch , which causes the Level property to be set to TraceLevel.Info . This causes the TraceError , TraceWarning , and TraceInfo properties of the traceSwitch to be true ; only the TraceVerbose property evaluates to false . Also, the third parameter of the WriteLineIf () method is used to categorize the output by specifying its value followed by a colon ( : ) and then the trace message. 9: You have the following segment of code in your program: ` Dim tl As EventLogTraceListener = _ New EventLogTraceListener("TraceLog") Trace.Listeners.Add(tl) Debug.Listeners.Add(tl) Trace.WriteLine("Sample Message") Debug.WriteLine("Sample Message") ` When you debug the program through Visual Studio .NET, how many times would the message "Sample Message" be written to the trace log? 1 2 3 4 A9: D. The message SampleMessage will be written four times. This is because two instances of EventLogTraceListeners are added to the Listeners collection. Any message generated by the Trace and Debug classes will be listed twice. Because the program is running in the Debug mode, both the Trace and Debug statements will be executed. The net effect is that both the Trace.WriteLine and Debug.WriteLine messages will be written twice, making four entries in the trace log. 10: Which of the following statements are true for the remote debugging of processes? (Select two.) Both the local and the remote machine should have Visual Studio .NET installed. Only the local machine needs Visual Studio.NET. Remote Components Setup is required on local machine. Remote Components Setup is required on the remote machine. A10: B, D. For remote debugging, Visual Studio .NET is not required on the remote machine. In this case, you need to run Remote Components Setup on the remote machine. You need to have Visual Studio .NET on the local machine in order to debug the remote processes. 11: While you are debugging in Visual Studio .NET, you want to watch the value of only those variables that are in use in the current and previous statements. Which of the following debugger windows is the easiest window to use to watch these variables? Autos Locals Me Watch A11: A. The Autos window gives you the most convenient access because it automatically displays names and values of all variables in the current statement and the previous statement at every step. 12: You are debugging a Windows form. The form involves long calculation and iterations. You want to break into the code to watch the value of variables whenever the value of intValue changes in the following statement: ` intValue = ProcessValue(intValue) ` Which of the following options will quickly allow you to achieve this? Run the application using step execution mode. Use the Step Out key to step out of execution from the ProcessValue function. Use the Immediate window to display the value of intValue before and after this line of code executes. Set a breakpoint at the given statement. Set the Hit Count option Break When Hitcount Is Equal To to 1. Set the breakpoint at the given statement. In the Breakpoint condition dialog box, enter intValue != intValue and check the Is True option. Set the Breakpoint at the given statement. In the Breakpoint condition dialog box, enter intValue and check the Has Changed option. A12: D. When you want to break into the code when a value of a variable changes, the quickest approach is to set a conditional breakpoint where you specify the variable name and check the Has Changed option. 13: You want to debug a remote process. The remote machine does not have Visual Studio .NET installed on it. Which of the following options should you choose? Start the process on the remote machine first and then launch Visual Studio .NET on the local machine. Attach the debugger to the running process. Break into the execution of the remote process. Open the project of the remote process in Visual Studio .NET, set a breakpoint, and execute the process. Copy the remote application project to the local machine and debug it by using the Visual Studio .NET debugger. Open the project of the remote process in Visual Studio .NET on the remote machine and then set a breakpoint. Run Visual Studio .NET on the local machine and attach the debugger to the project. A13: A. To debug a remote process, the process first needs to be started on the remote machine. You can then open Visual Studio .NET on the local machine and attach the debugger to the running process. After the debugger is attached, you can break into the code of the remote process and do step-by-step execution or set a breakpoint. 14: You create a serviced component named ConnectionDispenser . This component is stored in the DbUtils.dll assembly and is registered in the COM+ catalog. The serviced component is configured to be activated as a library application. You discover that the CreateNewConnection() method is not working as expected. You want to debug any calls to this method. What should you do? Open the ConnectionDispenser solution. Set a breakpoint on the CreateNewConnection() method. Start the debugger. Open the solution for the client program. Set a breakpoint on the statement that calls the ConnectionDispenser.CreateNewConnection() method. Start debugging the client program. Attach the debugger to the DbUtils.dll process. Set a breakpoint on the CreateNewConnection() method. Attach the debugger to a dllhost.exe process. Set a breakpoint on the CreateNewConnection() method. A14: B. A serviced component activated as a library application runs in the process of its caller. Therefore, to debug such an application, you can set a breakpoint in the client application and then step into the serviced component code. 15: You want to debug a remote process running on a Windows 2000 Server computer that is not in the domain of your local computer. The remote server has a full installation of Visual Studio .NET. The two domains do not have two-way trust established, but you do have a username and password on the remote Windows 2000 server. Which of the following would allow you to debug a process on that machine? Ask the administrator of the remote machine to start the Machine Debug Manager; then launch Visual Studio .NET on your local machine and attach the debugger to the remote process. Ask the administrator of the remote machine to include your username and password in the Debugger Users group; then launch Visual Studio .NET on your local machine and attach the debugger to the remote process. Use Terminal Server to log in to the remote machine. Launch Visual Studio on the remote machine and debug the process by attaching the debugger to it. Use Terminal Server to log in to the remote machine. Launch Visual Studio .NET on the local machine and debug the process by attaching the debugger to it. A15: C. If your local machine's domain does not have a two-way trust relationship with the remote computer's domain, you cannot debug a remote process. The only option you have is to log on to the remote machine by using Terminal Server, start Visual Studio .NET on the remote machine, and use Visual Studio .NET to attach the debugger to the process that is running on the same machine. You then debug as if you were debugging a process running on your local machine. 16: You are trying to debug a Windows application using Visual Studio .NET installed on your local machine. The Windows application is deployed on a remote server. When you attempt to debug the application, you get a DCOM configuration error. Which of the following steps should you take to resolve this problem? Add your account to the Power Users group on the local computer. Add your account to the Power Users group on the remote computer. Add your account to the Debugger Users group on the local computer. Add your account to the Debugger Users group on the remote computer. A16: D. If you get a DCOM configuration error while debugging, possibly you are not a member of the Debugger Users group on the remote machine. To resolve this, add your account on the remote machine to the Debugger Users group.
##### Suggested Readings and Resources

1. Windows Forms QuickStart Tutorial:

Diagnostics topics in the "How Do I" section.

Debugging topics in the "How Do I" section.

2. Visual Studio .NET Combined Help Collection:

"Introduction to Instrumentation and Tracing."

"Using the Debugger."

3. Kevin Burton. .NET Common Language Runtime Unleashed . Sams, 2002.

4. Richard Grimes. Developing Applications with Visual Studio .NET . Addison-Wesley, 2002.

 Top

MCAD/MCSD Training Guide (70-310): Developing XML Web Services and Server Components with Visual Basic(R) .NET and the .NET Framework
ISBN: 0789728206
EAN: 2147483647
Year: 2002
Pages: 166

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net