Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
1,06 MB
Nội dung
This shows the processes you can pick to debug. Make sure you have the Show system processes checkbox box selected, and pick the aspnet_wp.exe process - this is the ASP.NET worker process. Click the Attach… button to attach the debugger to the process, and then close the dialog. You can now load a page into the debugger (by using File | Open) and set break points (by clicking in the gray margin): This shows a breakpoint in a simple ASP.NET page coded using JScript (unlikely for most people, but there's a point to it - bear with me). This page simply instantiates a class called Programmer. If you now hit the page, you are flipped into the debugger at the set line: You can now step into the code for the component (assuming it was compiled with the /debug option): Now we've stepped into the constructor of the Programmer class, and notice that it is a Visual Basic class. We are almost at that point I was trying to make - let's go one step further and step into the base class: Now the point is made. We have a base class written in C#, which is sub-classed by a Visual Basic class, and used in a JScript ASP page. This becomes obvious when examining the call stack: This really reinforces the concept of language equality in the runtime, since you can debug through components written in different languages. Even if it were restricted to a single language, the fact that we have such a good debugger would be a great benefit in itself. SDK Debugger Features The SDK debugger has all of the great features that you'd expect from a high-end development environment, including: Stepping into, out of, and over code. Setting breakpoints on specific lines. Setting breakpoints on specific exceptions. Setting breakpoints on expressions. Viewing contents of variables. Viewing the call stack, threads, and modules. The two major features that aren't supported are debugging remote processes and EditandContinue. The latter of these means that the SDK debugger is a readonly debugger, so you can't edit code inline and continue the debugging process. You can only edit code externally, and the debugger recognizes that the file has changed (and will reload it if you desire), but the new changes will not take effect until the request is rerun. For these features you need the Visual Studio .NET Debugger. Debugging in Visual Studio .NET In Visual Studio .NET debugging is just a part of working with an integrated development tool. When building an application, all you have to do is set a breakpoint from within the code editor window and run your application: This looks similar to the SDK debugger, and supports the same set of features such as stepping and viewing of code and variables. Edit-and-Continue Edit-and-Continue gives you the ability to alter code while programs are running. This is due to the ability of the runtime to inject code into a running process. There are, however, some limitations: For running functions (anywhere in the call stack) you are limited to 64 bytes of additional variables. Outside of the call stack there is no limit. You cannot change resource files. You cannot change exception handling blocks. You cannot change data types. You cannot remove functions. In most cases you couldn't really call these limitations, as they are the sorts of alterations that would require more than a simple change. There's nothing special you have to do to enable this functionality. There are options to disable Edit-and-Continue, and to specify its various functions, but the defaults are all acceptable. All you have to do is retype code in the debugger when in break mode and the new code takes effect. Remote Debugging Remote debugging works in the same way as local debugging, except you have the option to debug a remote process. This is useful in situations where you have a separate server hosting the application. A full description of remote debugging is beyond the scope of this book, but consult the .NET documentation, under the section titled Remote Debugging Setup. Profiling and Performance Profiling is often one of those areas that never seems to have great value in some people's minds, but in certain respects it is the most important area of development. A slow web site is a great way to put off users and lose customers, and remains the bane of many administrators' lives. The simple fact is that performance testing often gets cut due to time constraints, as when deadlines get tight people cut things that don't have an immediate impact. The attitude is often to get the product shipped, and then release a performanceenhanced version at a later date. The reality is, of course, that users expect great things from a first release, and there should be no excuses for not delivering the bestperforming application. So, if we want the best possible performance from an application, how do we go about it? How do we find the areas of an application that need improvement, and go about testing those areas? Profiling is the act of gathering that data about an application, allowing us to see which areas take longest to execute. Performance testing isn't only about seeing how well an application performs in its current incarnation, but also includes: Baselining - This is the act of collecting performance data to be used as a comparison for future tests. Collecting metrics is important as applications and loads change - you need to have some base figures against which you can compare future analysis. Loading - Application performance decreases as the load increases, so you need to see how your application will perform under increasing load. That's the thing about web sites - the load is never guaranteed to stay the same - it can increase and decrease sharply as usage trends change. Stability - Web sites have to have constant availability as they have global reach. It is not possible to assume that no one will use your site at night, because your night may be your user's day. Therefore, you have to ensure your application stays stable, especially under load. As applications become more complex, so does testing. This is especially true now, where ASP.NET applications may be written with interoperability in mind, to provide integration with, or reuse of, existing technology. An example of this is the reuse of an existing COM data layer. This layer may be performing optimally in a current application, but when used from a .NET application does it become a bottleneck? At this stage, you have to ask if performance could be improved by rewriting the layer? This sort of question is discussed further in Chapter 23, where we look at migration and interoperability issues. There are three steps in the process of profiling: Instrumentation - Where you add profiling to your code. This could be adding Windows performance counters, or custom profiling statements to identify the execution of the code, as well as logging and tracing information. Sampling - Where you run your application to collect the profiling data. Analysis - Where you examine the collected data, and validate it against your baseline data. We will be concentrating on the first of these, although we will discuss the latter two options to show how the instrumentation process is used. Instrumentation Instrumentation is a bit like SchrÖdinger's Cat, where the act of viewing changes the outcome. In performance testing, you are examining how your application performs under certain conditions, and you add profiling to detect this. However, the profiling you add affects those very things you are testing - the performance metrics. The more profiling code you add to applications, the more you affect performance. So, the act of instrumentation is one that should be carefully handled. There is no harm in adding large amounts of profiling code as long as you understand the implications. The Trace class shown earlier provides some performance data for events, but this has to be manually viewed, and is not really designed for profiling. To profile, you want a simple way of adding profiling code as well as collecting information. This is provided by Performance Monitor Counters. Both the .NET framework and ASP.NET have counters (which we'll look at under the Analysis section), but to provide custom profiling you will need to create custom counters. Security The ASPNET account does not have sufficient privileges to read performance counter data, although it does have privilege to write performance counter data. To read performance counter data, the process requires Administrator or Power User permissions. To enable reading of data from counters, your ASP.NET pages will need to run under impersonation. Placing these pages in a separate directory and modifying the configuration file will allow this. When to Create and Remove Counters The creation and removal of counters is something you should think carefully about, as they are really installer and uninstaller features. If your application requires custom counters, then the counters should be created when the application is installed, and removed when the application is uninstalled. One problem with this approach is fitting it into ASP.NET applications where the xcopy deployment method is used. Ways to solve this could be to: Create an application installer so that the counters are created and removed in the correct place. Create a separate script or page to create and remove the counters. Check for the existence of counters in your application (perhaps the Application_OnStart event), and if missing create them. This leaves the problem of removing counters if the application is uninstalled, as well as a performance problem since you are checking for them every time the application starts. Of these solutions, the first option is certainly the best. Along with the question of when to create counters, there is the one of why? The answer is simple - create custom counters when you need to profile areas within your application. The supplied counters are perfect for looking at the application or ASP.NET as a whole, but aren't fine-grained enough to show you how the individual parts of your application are performing. So, it is only if you need this amount of information that you need to create custom counters. For example, imagine you have an e-commerce site, and you need to know how well the order processing section is performing. You will probably be storing the orders in a database, so you can see how many orders you have, but unless you also keep time information you can't see any performance metrics. Adding instrumentation to the order processing allows fine grained monitoring of this information. Custom Performance Counters The base class library supplies a set of classes for interacting with the Windows performance monitor, allowing both read-and-write access, as well as the creation of custom objects and counters. These objects are: Object Description PerformanceCounterCategory A counter category, to contain individual counters. PerformanceCounter The details of an individual performance counter. CounterCreationData The details required for the creation of a counter. CounterCreationDataCollection A collection of performance counter creation details, for creating multiple counters in a category. CounterSample A sample of data from a counter. The first two of these objects are easy to relate to, by looking at the Add Counters screen of the Windows Performance Monitor: The Performance object: drop down list on the dialog corresponds to the PerformanceCounterCategory, and the counters list corresponds to the PerformanceCounter. Just like the above dialog, the use of the counter objects isn't limited to the local machine - many of the methods allow the addition of a machine name, allowing manipulation of counters on remote machines (assuming the correct permissions). The PerformanceCounterCategory Object Let's first look at the category object, as this contains details for the category itself, allowing creation of new categories and counters as well as the retrieval of category and counter information. It has three properties: Property Description CategoryName The name of the category. CategoryHelp Text describing the category. MachineName The machine upon which the category is installed. The methods are more extensive: Method Description CounterExists Indicates whether or not the selected counter exists. Create Creates a category and a counter or counters. Delete Deletes a category and counters. Exists Indicates whether or not the category exists. GetCategories Returns an array of categories. GetCounters Returns an array of counters for the category. GetInstanceNames Returns an array of names of counter instances. InstanceExists Indicates whether or not the counter instance exists. ReadCategory Returns a collection of all category and instance data. Many of these methods are overloaded, allowing several forms of use. For example, the CounterExists() method has three forms: CounterExists(CounterName) CounterExists(CounterName, CategoryName) CounterExists(CounterName, CategoryName, MachineName) The first case of these requires the PerformanceCounterCategory object to have been initialized to an existing category. For example: Dim PC As New PerformanceCounterCategory("Wrox") If PC.CounterExists("MyCounter") Then End If The latter two cases are static methods, and don't require an object instance. For example: If PerformanceCounterCategory.CounterExists("MyCounter", "Wrox") Then End If or: If PerformanceCounterCategory.CounterExists("MyCounter", "Wrox", "Eeyore") Then End If Creating Custom Performance Counters The first point to note about creating counters is that they can only be created in new categories. This means that you cannot modify any of the existing categories, and that if you want to add counters to a custom category, you need to remove the category first. To create counters, you use the Create() method of the PerformanceCounterCategory object, which has several forms: Create(CategoryName, CategoryHelp, CounterName, CounterHelp) Create(CategoryName, CategoryHelp, CounterName, CounterHelp, MachineName) Create(CategoryName, CategoryHelp, CounterCreationDataCollection) Create(CategoryName, CategoryHelp, CounterCreationDataCollection, MachineName) The first two of these allow a category and a single counter to be created. For example: PerformanceCounterCategory.Create("Wrox", "Wrox Press Counters", _ "Counter1", "This counter is counter 1") The second two methods use a collection of CounterCreationData objects, allowing the creation of multiple counters, as well as being able to specify the type of counter (which defaults to RateOfCountsPerSecond32-more on types later). This object can be constructed like so: Dim CCD As CounterCreationData CCD = New CounterCreationData("Counter1", "This counter is counter 1", _ PerformanceCounterType.NumberOfItems32) or, alternatively using the properties: Dim CCD As New CounterCreationData() [...]... perhaps in a spreadsheet You can also use the PerformanceCounter object to query counters, although this is a task best left to applications other than ASP.NET This is because accurate monitoring depends on regular sampling of data, and this isn't a task that ASP.NET is suited to In this case you'd be better off building a Windows Forms application that could sample the data at regular intervals Summary... manage the story of getting NET to work with the pre-.NET world In particular we will look at: Migrating ASP applications to ASP.NET Changing from JScript and VBScript to their NET equivalents Using existing COM components from NET Using NET components from COM Despite the fact that ASP.NET is such a radical change from ASP, there's an excellent migration path, as well as great support for working alongside... benefit Integrate Integration gives us the ability to add new ASP.NET features to existing ASP applications, or perhaps to migrate only selected parts of an application In many ways this is a good approach, but it also comes with dangers, the two most obvious of which are: Built-in Session and Application state cannot be shared between ASP and ASP.NET applications Performance, as crossing the managed/un-managed... all, the application will still work, and the new ASP.NET code should run faster, so the benefit of using new code might equal out any performance drop Also, when all things are considered, the boundary crossing is light compared to some other actions (such as database access) The first bullet point, though, is a big problem - you can easily integrate ASP.NET pages into an ASP application, but there's... as a database), or doesn't use the in-built state handling, your options are limited Integrating ASP.NET applications with existing COM components only suffers from the minor performance hit of the unmanaged/managed code boundary, unless they use the ASP context In this case you may need to alter your ASP.NET pages We'll look at this topic later Rewrite Rewriting is the option many of us would like... sometimes a good old-fashioned wooden train set works fine ASP.NET There are many changes to take into account when looking purely at ASP pages The most obvious are the server controls and the postback architecture These have been covered extensively in earlier chapters of the book, so now we'll move on to other features that still exist in ASP.NET, but that are different from ASP We'll also abbreviate... new ones One significant change is the removal of the ASPError object, as error handling is now managed by exceptions The Application Object ASP.NET application state handling is implemented by the HttpApplicationState class in the System.Web namespace Although ASP.NET supports ASP functionality by way of the Contents and StaticObjects collections, there are some minor differences, which may confuse... used more than one server-side language, but with ASP.NET you must use a single language per page If you need to use multiple languages then you'll have to use User Controls or custom controls, which can be in any language This only affects individual pages - multiple pages in an application can be in different languages Script Blocks Procedures in ASP.NET pages have to reside within proper script... the inverse of Timer100ns: 100-Timer100ns Analysis There are two sets of information you can use to evaluate the performance of your web applications - the NET performance counters, and custom counters ASP.NET has an extensive list of counters, which are well documented in the framework SDK Analysis of custom counters is application-specific, and there are no hard rules as to what you should analyze... 1 CPU) There is also a _Total instance, which aggregates the values for other instances Some counters, such as Memory, don't have specific instances, as they are concerned with a single object What's especially noteworthy about this is that instances apply to a Performance object (or category), and not to individual counters You cannot have two counters in the same category with different instances . CounterMultiTimer 100 ns is an average sample among multiple items per 10 0 nanoseconds: 10 0.((NewSample-OldSample)/((NewTime-OldTime) / 10 0ns))/NumberOfItemsSampled CounterMultiTimer 100 nsInverse. sampled. For display in terms of a percentage. Timer 100 ns Timer sampling every 10 0 nanoseconds. Timer 100 nsInverse The inverse of Timer 100 ns. Used when the object is not in use. The type of. the inverse of CounterMultiTimer 100 ns: 10 0.NumberOfItemsSampled-CounterMultiTimer 100 ns CounterTimer is the percentage of items over the sample period: 10 0.((NewSample-OldSample)/(NewTime-OldTime))