饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 123 页

作者:Nick Randolph/等 当前章节:15401 字 更新时间:2026-6-18 14:51

understand the runtime behavior of your source code and quickly track down logic errors.

call stack

As applications grow in complexity, it is quite common for the execution path to become difficult to

follow. The use of deep inheritance trees and interfaces can often obscure the execution path. This

is where the call stack is useful. Each path of execution must have a finite number of entries on the

stack (unless a cyclic pattern emerges, in which case a stack overflow is inevitable). The stack can be

viewed using the Call Stack window (Debug .

Windows . Call Stack), shown in Figure 39-8.

fiGure 39-8

Using the Call Stack window, it is easy to navigate up the execution path to determine from where

the current executing method is being called. You can do this by clicking any of the rows in the call

stack, known as a stack frame. Other options available from the call stack, using the right-click

context menu, enable viewing the disassembler for a particular stack frame, setting breakpoints,

and varying what information is displayed.

834 .

chaPter 39 uSing The debugging WindoWS

threads

Most applications make use of multiple threads at some point. In particular for Windows applications,

in order for the user interface to always appear responsive, it is important to run time-consuming tasks

on a thread separate from the main application. Of course, concurrent execution of threads makes

debugging more difficult, especially when the threads are accessing the same classes and methods.

Figure 39-9 shows the Threads window (Debug .

Windows . Threads), which lists all the active

threads for a particular application. Notice that in addition to the threads created in the code,

additional background threads have been created by the debugger. For simplicity, the threads used

by this application, including the main user interface thread, have been given names so they can

easily be distinguished.

fiGure 39-9

The Threads window shows a yellow arrow next to the thread that is currently being viewed in the

code window. To navigate to another thread, simply double-click that thread to bring the current

location of that thread into view in the code window and update the call stack to reflect the new

thread.

In Break mode, all threads of an application are paused. However, when you are stepping through

your code with the debugger, the next statement to be executed may or may not be on the same

thread you are interested in. If you are only interested in the execution path of a single thread, and the

execution of other threads can be suspended, right-click the thread in the Threads window and select

Freeze from the context menu. To resume the suspended thread, select Thaw from the same menu.

Debugging multi-threaded applications is explained further in Chapter 43.

Modules

The Modules window (Debug .

Windows . Modules), shown in Figure 39-10, displays a list

of assemblies that are referenced by the running application. Those assemblies that make up the

application will also have debugging symbols loaded, which means that they can be debugged

without dropping into the disassembler. This window is particularly useful if you want to find out

what version of an assembly is currently loaded and where it has been loaded from.

The Memory Windows .

835

fiGure 39-10

In Figure 39-10 the symbols have been loaded for the DebugApp1.exe application. All the other

assemblies have been skipped, because they contain no user code and are optimized. If an

appropriate symbol file is available, it is possible to load it for an assembly via the Load Symbols

option from the right-click context menu.

Processes

Building multi-tier applications can be quite complex, and it is often necessary to have all the tiers

running. To do this, Visual Studio 2010 can start multiple projects at the same stage, enabling

true end-to-end debugging. Alternatively, you can attach to other processes to debug running

applications. Each time Visual Studio attaches to a process, that process is added to the list in the

Processes window (Debug .

Windows . Processes). Figure 39-11 shows a solution containing two

Windows applications and a web application.

fiGure 39-11

The toolbar at the top of the Processes window enables you to detach or terminate a process that is

currently attached, or attach to another process.

the MeMory windows

The next three windows are typically used for low-level debugging when all other alternatives have

been exhausted. Stepping into memory locations, using a disassembler, or looking at registry values

requires a lot of background knowledge and patience to analyze and make use of the information

that is presented. Only in very rare cases while developing managed code would you be required to

perform debugging at such a low level.

836 .

chaPter 39 uSing The debugging WindoWS

Memory windows 1–4

The four Memory windows can be used to view the raw contents of memory at a particular address.

Where the Watch, Autos, and Locals windows provide a way of looking at the content of variables,

which are stored at specific locations in memory, the Memory window shows you the big picture

of what is stored in memory.

Each of the four Memory windows (Debug

.

Windows . Memory 1 to Memory 4)

can examine different memory addresses

to simplify debugging your application.

Figure 39-12 shows an example of the

information that can be seen using this

window. The scrollbar on the right of

the window can be used to navigate forward or backward through the memory addresses to view

information contained in neighboring addresses.

disassembly

Interesting debates arise periodically over the relative performance of two different code blocks.

Occasionally this discussion devolves to talking about which MSIL instructions are used, and why

one code block is faster because it generates one fewer instruction. Clearly, if you are calling that

code block millions of times, disassembly might give your application a significant benefit. However,

more often than not, a bit of high-level refactoring saves much more time and involves much less

arguing. Figure 39-13 shows the Disassembly window (Debug .

Windows . Disassembly) for a

LinkLabel click — the run time is about to construct a new Customer object. You can see MSIL

instructions that make up this action.

fiGure 39-12

fiGure 39-13

You can see from Figure 39-13 that a breakpoint has been set on the call to the constructor and that

the execution point is at this breakpoint. While still in this window you can step through the lines

of MSIL and review what instructions are being executed.

registers

Using the Disassembly window to step through MSIL instructions can become very difficult to

follow as different information is loaded, moved, and compared using a series of registers. The

intelliTrace (Ultimate edition only) .

837

Registers window (Debug . Windows . Registers), shown in Figure 39-14, enables the contents of

the various registers to be monitored. Changes in a register value are highlighted in red, making it

easy to see what happens as each line is stepped through in the Disassembly window.

fiGure 39-14

intellitrace (ultiMate edition only)

One of the more interesting new features in the Ultimate edition of Visual Studio is IntelliTrace. One

of the limitations of traditional debuggers is that they only show a snapshot of the state of the

application at a single point in time. The IntelliTrace feature of Visual Studio collects information

during the debugging session, thereby allowing you to go back to an earlier point and view the

application state at that time.

You can think of IntelliTrace as your very own black box flight recorder for

debugging.

IntelliTrace has two data collection levels. By default it collects information about diagnostic

events only, such as entering Break mode, stepping through code in the debugger, or when an

exception is thrown. You can also configure IntelliTrace to collect very detailed information,

such as the details of every function call, including the parameters passed to that function and

the values that were returned.

The IntelliTrace Events window (Debug .

Windows . IntelliTrace Events) shown in

Figure 39-15, enables you to navigate to past

diagnostic events. When you click a past

event, the execution point in the code window

changes from a yellow arrow to a red arrow

with a stopwatch icon. The call stack is also

updated to reflect the historical state of the

application.

If you have enabled the detailed data collection

level, you will be able to use the Autos and

Locals windows to inspect the contents of

variables that have been collected.

fiGure 39-15

838 .

chaPter 39 uSing The debugging WindoWS

You can change the data collection level or disable it completely from the IntelliTrace tab in the

options menu (Tools . Options). You can also configure IntelliTrace to exclude certain assemblies

from the data collection.

You can expect a reasonable performance impact if you enable the detailed data

collection level. You must also ensure that you have enough free disk space to

collect this data. The Edit and Continue functionality is also disabled for the

detailed level.

IntelliTrace can also debug logs created by the new Visual Studio software test tools, Test and Lab

Manager. Chapter 55 provides more information on IntelliTrace.

the Parallel debuGGinG windows

Nowadays it is almost impossible to purchase a new computer that has a single processor. The trend

to many - core CPUs, which has been necessary due to physical limitations that have been reached in

CPU architecture, will certainly continue into the future as the primary way for hardware vendors

to release faster computers.

Unfortunately, software that has not been written to explicitly run on multiple CPUs will not run

faster on a many-core machine. This will be a problem for many users who have been conditioned

over the past couple of decades to expect their applications to run faster when they upgrade to

newer hardware.

The solution is to ensure that our applications can execute different code paths concurrently on

multiple CPUs. The traditional approach is to develop software using multiple threads or processes.

Unfortunately, writing and debugging multi-threaded applications is very difficult and error prone,

even for an experienced developer.

Microsoft has recognized this issue, and has introduced a number of new features with Visual Studio

2010 and .NET Framework version 4.0 aimed to simplify the act of writing such software. The Task

Parallel Library (TPL) is a set of extensions to the .NET Framework to provide this functionality. The

TPL includes new language constructs, such as the Parallel.For and Parallel.ForEach loops, and

new collections that are specifi cally designed for concurrent access including ConcurrentDictionary

and ConcurrentQueue.

In the new System.Threading.Tasks namespace are several new classes that greatly simplify the

effort involved in writing multi-threaded and asynchronous code. The Task class is very similar to a

thread; however, it is much more lightweight and therefore performs much better at run time.

Writing parallel applications is only one part of the overall development life cycle — you also need

effective tools for debugging parallel applications. To that end Visual Studio 2010 has introduced

two new debugging windows — the Parallel Stacks window and the Parallel Tasks window.

The Parallel Debugging Windows .

839

Parallel stacks

You will recall from earlier in the chapter, the Call Stacks window can be used to view the execution

path of the current line of code when debugging. One of the limitations of this window is that you

can see only a single call stack at a time. To see the call stack of other threads, you must use the

Threads window or Debug Location toolbar to switch the debugger to a different thread.

The Parallel Stacks window (Debug .

Windows . Parallel Stacks), shown in Figure 39-16, is one

of the more useful windows for debugging multi-threaded and parallelized applications. It provides

not just a way to view multiple call stacks at once, but also provides a graphical visualization of the

code execution including showing how multiple threads are tied together and the execution paths

that they share.

fiGure 39-16

The Parallel Stacks window in Figure 39-16 shows an application that is currently executing seven

threads. The call graph is read from bottom to top. The Main thread appears in one box, and four

others threads are grouped together in another box. The reason these four threads are grouped is

because they share the same call stack (that is, each thread called FuncA, which then called FuncB,

which in turn called FuncC). After these threads executed FuncC, their code paths diverged. One

thread executed FuncD, which then called FuncE. A different thread executed FuncF, FuncG, and

then FuncH. The other two threads executed FuncI, which called FuncJ, and so on. You can see

how visualizing all of the call stacks at once provides a much better understanding on the state

of the application as a whole and what has led to this state, rather than just the history of an

individual thread.

A number of other icons are used on this screen. The execution point of the current thread is shown

with a yellow arrow. In Figure 39-16, this is against FuncE in a box on the left-hand side of the

diagram. Each box that the current thread has progressed through as part of its execution path is

840 .

chaPter 39 uSing The debugging WindoWS

highlighted in blue. The wavy lines (also known as the cloth thread icon) shown against the call to

FuncK in the top-right box indicates that this is the current execution point of a non-current thread.

As shown in Figure 39 - 16, you can hover over the thread count label at the top of each box to see the

Thread ID ’s of the applicable threads. You can also right - click any entry in a call stack to access various

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页