Apply Your Knowledge
Exercises
Creating a Custom Trace Switch
The TraceSwitch and BooleanSwitch classes are two classes that provide trace switch functionality. If you need different trace levels or different implementations of the Switch class, you can inherit from the Switch class to implement your own custom trace switches.
In this exercise, you will learn how to create a custom switch. You will create a FactorialSwitch class that can be set with four values (Negative (-1), Off (0), Overflow (1), and Both (2)) for the Factorial Calculator form. The class will have two properties: Negative and Overflow.
Estimated time:
25 minutes.
Launch Visual Studio .NET. Select File, New, Blank Solution, and name the new project 320C09Exercises. Add a new Windows application project to the solution. Name the project Exercise9_1. Using the Add Class Wizard, add a new class to the project. Name the class FactorialSwitch and modify the class definition so that it has the following code:
using System;
using System.Diagnostics;
namespace Exercise9_1
{
// The possible values for
// the new switch
public enum FactorialSwitchLevel
{
Negative = -1,
Off = 0,
Overflow = 1,
Both = 2
}
public class FactorialSwitch : Switch
{
public FactorialSwitch(
string displayName,
string description)
: base(displayName, description)
{
}
public bool Negative
{
get
{
// return true if the
// SwitchSetting is
// Negative or Both
if( (SwitchSetting == -1) ||
(SwitchSetting == 2))
return true;
else
return false;
}
}
public bool Overflow
{
get
{
// return true if the
// SwitchSetting is
// Overflow or Both
if ((SwitchSetting == 1) ||
(SwitchSetting == 2))
return true;
else
return false;
}
}
}
}
In Solution Explorer, right-click Form1.cs and rename it FactorialCalculator. Open the Properties window for this form and change its Name property to FactorialCalculator and Text property to Factorial Calculator Exercise 9_1. Switch to the code view of the form and modify the Main() method to launch FactorialCalculator rather than Form1. Place two TextBox controls (txtNumber and txtFactorial), three Label controls and a Button control (btnCalculate) on the form and arrange the controls as shown earlier in Figure. Open FactorialCalculator.cs in the code view. Add the following using directive:
using System.Diagnostics;
Add the following code in the class definition:
static FactorialSwitch facSwitch =
new FactorialSwitch("FactorialTrace",
"Trace the factorial application " +
"using Factorial Switch");
Attach a Click event handler to the btnCalculate control with the following code:
private void btnCalculate_Click(
object sender,
System.EventArgs e)
{
int intNumber = Convert.ToInt32(
txtNumber.Text);
if (facSwitch.Negative)
{
// make a debug assertion
Debug.Assert(intNumber >= 0,
"Invalid value",
"negative value in debug mode");
}
int intFac = 1;
for (int i = 2; i <= intNumber; i++)
{
intFac = intFac * i;
}
if (facSwitch.Overflow)
// write a debug message
// if the condition is true
Debug.WriteLineIf(intFac < 1,
"There was an overflow",
"Factorial Program Debug");
txtFactorial.Text = intFac.ToString();
}
In Solution Explorer, select View All Files from the toolbar. Navigate to the bin\debug folder. Right-click the debug folder and select Include in Project. Select the debug folder again and select Add, Add New Item from the context menu. Choose to create an XML file and name it Exercise9_1.exe.config. 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>
Set Exercise9_1 as the startup project. Run the project, using the default Debug configuration. Notice that the assertion failed message is displayed only if the switch is set with the value –1 or 2. Similarly, the overflow message is displayed in the output window only if the switch value is set to 1 or 2. Modify the program to change all Debug statements to Trace statements. Copy the XML configuration file to the bin\Release folder in the project and then repeat step 12, using the Release configuration.
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.
Using Visual C# .NET to Debug SQL Server Stored Procedures
You can perform step-by-step execution of SQL Server stored procedures in Visual C# .NET. This exercise shows you how.
Estimated time:
30 minutes.
Add a new Windows application project to the solution. Name the project Exercise9_2. Rename the Form1.cs form MostExpensiveProdcuts.cs. Switch to code view and change all occurrences of Form1 to MostExpensiveProducts. Select Project, Properties from the main menu. Select Debugging under the Configuration Properties node in the left pane of the Property Pages window. In the right pane, under the Debuggers node, choose true for Enable SQL Debugging, as shown in Figure.

Drag a SqlDataAdapter component to the form. 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. 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. Click Next and then click Finish. A SqlConnection component is created in the component tray.

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 from the check box list. Click OK to create a dataSet11 component in the component tray. Place a Button control (btnGetProducts) and a DataGrid control (dataGrid1) on the form. Change the DataGrid control's DataSource property to dataSet1 and DataMember property to Ten Most Expensive Products. Add the following code in the Click event of the Button control:
private void btnGetProducts_Click(
object sender, System.EventArgs e)
{
sqlDataAdapter1.Fill(this.dataSet11);
}
Insert a breakpoint in the Click event handler, at the point of a call to the Fill() method of the sqlDataAdapter1 object. Open Server Explorer. Open the Data Connections node and select the stored procedure Ten Most Expensive Products. 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.

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 F11. 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, notice the SELECT statement enclosed in an outline (blue on your screen), which represents each step in the stored procedure (if the step occupies more than a line).
EXAM TIP
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.
Using Visual C# .NET to Set Conditional Breakpoints
This exercise shows you how to set conditional breakpoints. I'll set a breakpoint in the factorial calculation to break when the Factorial value overflows (that is, it becomes negative).
Estimated Time:
30 minutes.
Add a new Windows application project to the solution. Name the project Exercise9_3. In Solution Explorer, right-click Form1.cs and rename it FactorialCalculator. Open the Properties window for this form and change its Name property to FactorialCalculator and Text property to Factorial Calculator Exercise 9_3. Switch to the form's code view and modify the Main() method to launch FactorialCalculator instead of Form1. Place two TextBox controls (txtNumber and txtFactorial), three Label controls and a Button control (btnCalculate) to the form and arrange the controls as shown earlier in Figure. Open FactorialCalculator.cs in the code view. Add the following using directive:
using System.Diagnostics;
Attach a Click event handler to the btnCalculate control and add the following code in the event handler:
private void btnCalculate_Click(
object sender, System.EventArgs e)
{
int intNumber =
Convert.ToInt32(txtNumber.Text);
int intFac = 1;
for (int i = 2; i <= intNumber; i++)
{
intFac = intFac * i;
}
txtFactorial.Text = intFac.ToString();
}
Right-click the following line in the Click event handler for the Button control and select New Breakpoint from the context menu.
intFac = intFac * i;
This opens the New Breakpoint dialog box. Select the File tab. You will note that File, Line, and Character position are already marked correctly. Click the Condition button to open the Breakpoint Condition dialog box. Set the values in the dialog box as shown in Figure. Select the Condition check box. Enter intFac < 1 in the Condition text box and select the Is True option. Click OK twice to dismiss the New Breakpoint dialog box.

Run the project using the default Debug configuration. Enter a bigger number—say, 100—and click the Calculate button. You will notice that the running page breaks into the debugger when intFac has a negative value and the breakpoint is reached.
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 message if the condition evaluates to false. | | 3: | What is the main purpose of the 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:
| The main advantage of trace switches is that 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 have its return type set to void. | | 7: | What are the purposes of the #error and #warning preprocessing directives? | |
A7:
| The #error and #warning preprocessing directives let you explicitly generate errors and warnings from code. The compiler reports errors and warnings in the same way it reports other compile-time errors and warnings. | | 8: | What are the three commands can you use to step through code while debugging? | |
A8:
| 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). | | 9: | What happens when you put a breakpoint in code? | |
A9:
| When the debugger encounters a breakpoint in code, it pauses the execution of the application. The execution can be resumed via the stepping commands. | | 10: | What are some of the different windows that are available for debugging? | |
A10:
| Visual Studio .NET provides a variety of windows to ease the debugging process. Some of these windows are This, Locals, Autos, Watch, Call Stack, and Breakpoints. | | 11: | How can you attach the debugger to a running process in Visual C# .NET? | |
A11:
| To attach the debugger to a running process, open Visual C# .NET, invoke the Processes dialog box, select the process from the list of processes, and click the Attach button. | | 12: | To verify that remote debugging is enabled on a system, what should you check? | |
A12:
| 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 so that you can remotely access the machine for debugging. | | 13: | How can you debug an already-running COM+ application? | |
A13:
| 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. For more information, see the section "Executing Tests" in this chapter. | | 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?
FileStream fileLog = new
File.Create("RemObject.log");
EventLog eventLog = new
EventLog("RemObject");
Trace.WriteLine(fileLog,
"Sample Message");
Trace.WriteLine(eventLog,
"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");
EventLogTraceListener eventLog =
new EventLogTraceListener("RemObject");
TextFileTraceListeners fileLog =
new TextFileTraceListeser("RemObject.log");
eventLog.WriteLine("Sample Message");
fileLog.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. For more information, see the section "Trace Listeners" in this chapter. | | 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 the Debug.Write statement to print the value of the @Sales variable. Use the Trace.Write statement 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 procedure during its step-by-step execution. For more information, see the section "Analyzing Program State to Resolve Errors" and Exercise 9.2 in this chapter. | | 4: | In your C# program, you have the following lines of code:
TraceSwitch myTraceSwitch =
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. For more information, see the section "Trace Switches" in this chapter. | | 5: | You are developing a retail Web site for selling readymade garments. Your application has a bunch of serviced components that execute 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 with the following code segment:
try
{
// the business logic goes here
}
catch
{
//log any error messages here
}
finally
{
ContextUtil.SetComplete();
}
| |
A5:
| C. When you debug a program, the transaction may not complete in the set timeframe (the default is 60 seconds). In that case, the program throws 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 on the computer. For more information, see the section "Debugging a Serviced Component" in this chapter. | | 6: | You are asked to implement tracing in an XML Web service so that the application displays both warning and error messages when the Debug configuration is used to run it and should display only error messages when the Release configuration of Visual C# .NET is used to run it. Which of the following code segments best meets this requirement?
TraceSwitch traceSwitch =
new TraceSwitch("MySwitch",
"Error and Warning Switch");
#if DEBUG
traceSwitch.Level = TraceLevel.Warning;
#else
traceSwitch.Level = TraceLevel.Error;
#endif
Trace.WriteLineIf(traceSwitch.TraceWarning,
"Warning Message");
Trace.WriteLineIf(traceSwitch.TraceError,
"Error Message");
TraceSwitch traceSwitch = new TraceSwitch(
"MySwitch",
"Error and Warning Switch");
#if DEBUG
traceSwitch.Level = TraceLevel.Warning;
#else
traceSwitch.Level = TraceLevel.Error;
#endif
Debug.WriteLineIf(traceSwitch.TraceWarning,
"Warning Message");
Debug.WriteLineIf(traceSwitch.TraceError,
"Error Message");
TraceSwitch traceSwitch = new TraceSwitch(
"MySwitch",
"Error and Warning Switch");
#if TRACE
traceSwitch.Level = TraceLevel.Warning;
#else
traceSwitch.Level = TraceLevel.Error;
#endif
Trace.WriteLineIf(traceSwitch.TraceWarning,
"Warning Message");
Trace.WriteLineIf(traceSwitch.TraceError,
"Error Message");
TraceSwitch traceSwitch = new TraceSwitch(
"MySwitch",
"Error and Warning Switch");
#if TRACE
traceSwitch.Level = TraceLevel.Error;
#else
traceSwitch.Level = TraceLevel.Warning;
#endif
Trace.WriteLineIf(traceSwitch.TraceWarning,
"Warning Message");
Trace.WriteLineIf(traceSwitch.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 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. For more information, see the section "Trace Switches" in this chapter. | | 7: | The configuration file of an XML Web service has the following contents:
<system.diagnostics>
<switches>
<add name="BooleanSwitch"
value="-1" />
<add name="TraceLevelSwitch"
value="33" />
</switches>
</system.diagnostics>
You are using the following statements to create switch objects in your code:
BooleanSwitch booleanSwitch =
new BooleanSwitch(
"BooleanSwitch", "Boolean Switch");
TraceSwitch traceSwitch = new TraceSwitch(
"TraceLevelSwitch", "Trace Switch");
Which of the following options is correct regarding the values of these switch objects?
The booleanSwitch.Enabled property is set to false and traceSwitch.Level is set to TraceLevel.Verbose. The booleanSwitch.Enabled property is set to true and traceSwitch.Level is set to TraceLevel.Verbose. The booleanSwitch.Enabled property is set to false and traceSwitch.Level is set to TraceLevel.Error. The booleanSwitch.Enabled property is set to false and traceSwitch.Level is set to TraceLevel.Info.
| |
A7:
| B. For BooleanSwitch, a value of 0 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. For more information, see the section "Trace Switches" in this chapter. | | 8: | You are developing a Windows application. Your application's configuration files have the following code:
<system.diagnostics>
<switches>
<add name="TraceLevelSwitch"
value="3" />
</switches>
</system.diagnostics>
You have written the following tracing code in your program:
static TraceSwitch traceSwitch =
new TraceSwitch(
"TraceLevelSwitch",
"Trace the application");
[Conditional("DEBUG")]
private void Method1()
{
Trace.WriteLineIf(
traceSwitch.TraceError,
"Message 1", "Message 2");
}
[Conditional("TRACE")]
private void Method2()
{
Trace.WriteLine("Message 3");
}
private void btnCalculate_Click(
object sender, System.EventArgs e)
{
if(traceSwitch.TraceWarning){
Trace.WriteLine("Message 10");
Method1();
}
else{
Trace.WriteLineIf(
traceSwitch.TraceInfo,
"Message 20");
Method2();
}
if (traceSwitch.TraceError)
Trace.WriteLineIf(
traceSwitch.TraceInfo,
"Message 30");
Trace.WriteLineIf(
traceSwitch.TraceVerbose,
"Message 40");
}
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. For more information, see the section "Trace Switches" in this chapter. | | 9: | You have the following segment of code in your program:
EventLogTraceListener traceListener =
new EventLogTraceListener("TraceLog");
Trace.Listeners.Add(traceListener);
Debug.Listeners.Add(traceListener);
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. 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. For more information, see the section "Trace Listeners" in this chapter. | | 10: | Which of the following statements are true for 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 the 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 to debug the remote processes. For more information, see the section "Debugging a Remote Process" in this chapter. | | 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 statement and the previous statement. Which of the following debugger windows is the easiest window to use to watch these variables?
Autos Locals This 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. For more information, see the section "Analyzing Program State to Resolve Errors" in this chapter. | | 12: | You are debugging a Windows form. The form involves long calculations 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 the 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. For more information, see the section "Setting Breakpoints and Stepping Through Program Execution" and Exercise 9.3 in this chapter. | | 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. For more information, see the section "Debugging a Remote Process" in this chapter. | | 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. For more information, see the section "Debugging a Serviced Component" in this chapter. | | 15: | You want to debug a remote process that is running on a Windows 2000 Server computer that is not in your local computer's domain. 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, and 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, and 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 then 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. For more information, see the section "Debugging a Remote Process" in this chapter. | | 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. For more information, see the section "Debugging a Remote Process" in this chapter. |
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.
|