240 likes | 555 Views
ASP.NET Best Practices. Dawit Wubshet Park University. StringBuilder. The StringBuilder class starts with a default initial capacity of 16. Strings less than the initial capacity are stored in the StringBuilder object.
E N D
ASP.NET Best Practices Dawit Wubshet Park University
StringBuilder • The StringBuilder class starts with a default initial capacity of 16. • Strings less than the initial capacity are stored in the StringBuilder object. • The initial capacity of the buffer can be set by using the following overloaded constructor: public StringBuilder (int capacity); For example: StringBuilder sb = new StringBuilder(2000);
StringBuilder • Use StringBuilder when you need to concatenate strings multiple times. • // using String and '+' to append String str = "Some Text"; for ( ... loop several times to build the string ...) { str = str + " additional text "; } // using String and .Append method to append StringBuilder strBuilder = new StringBuilder("Some Text "); for ( ... loop several times to build the string ...) { strBuilder.Append(" additional text "); }
StringBuilder • Use StringBuilder when the number of appends is unknown. • Code sample: for (int i=0; i< Results.Count; i++) { StringBuilder.Append (Results[i]); }
StringBuilder • Treat StringBuilder as an accumulator or reusable buffer. • Avoids the allocations of temporary strings during multiple append iterations. Some of the scenarios where this helps are as follows: • Concatenating strings: You should always prefer the following approach to string concatenation when using StringBuilder. StringBuilder sb; sb.Append(str1); sb.Append(str2); Use the preceding code rather than the following. sb.Append(str1+str2);
StringBuilder • Concatenating strings from various functions. Example: StringBuilder sb; sb.Append(f1(...)); sb.Append(f2(...)); sb.Append(f3(...)); The preceding code snippet results in temporary string allocations for the return values by the functions f1 (...), f2 (...), f3 (...). • This can be avoided by following this approach: void f1( sb,...); void f2( sb,...); void f3( sb,...);
Round Trips to the Server • Round trips to a server needs to be reduced by: • Prevalidating data on the client-side. Use validation controls to implement client-side validation of user input. Example: <asp:requiredfieldvalidator id="rqrdUsername" runat="server" Display=“Dynamic" ControlToValidate="txtUsername"> Required.</asp:requiredfieldvalidator> • Using AJAX, Javascript.
View State • View state is turned on in ASP.NET by default. • Disable view state if you do not need it. For example, you might not need view state because your page is output-only or because you explicitly reload data for each request. You do not need view state when the following conditions are true: ● Your page does not post back. ● You do not handle server control events. ● You repopulate controls with every page refresh.
View State • Ways to disable view state at various levels: • To disable view state for all applications on a Web server, configure the <pages> element in the Machine.config file as follows: <pages enableViewState="false" /> To disable view state for a single control on a page, set the EnableViewState property of the control to false: //Run time yourControl.EnableViewState = false; //Design time <asp:datagrid EnableViewState="false" runat="server" /> • To disable view state for a single page, use the @ Page directive as follows: <%@ Page EnableViewState="false" %>
Redirecting Between Pages • Where possible, use the Server.Transfer method instead of the Response.Redirect method. • If you need authentication and authorization checks during redirection, use Response.Redirect. • When you use Response.Redirect, ensure you use the overloaded method that accepts a Boolean second parameter: Response.Redirect(“Adminlogin.aspx”, false); • To transfer to pages in other applications, you must use Response.Redirect.
Resource Acquisition & Disposing • Open critical, limited, and shared resources just before you need them, and release them as soon as you can. Critical, limited, and shared resources include resources such as database connections, network connections, and transactions. For example: conn.Open(); SqlCommand comm = new SqlCommand(“park_sp_GetAMember”, conn); Instead of: conn.Open(); restructureInput(); … SqlCommand comm = new SqlCommand(“park_sp_GetAMember”, conn);
Resource Acquisition & Disposing • Use Try/Finally on disposable resources. To guarantee resources are cleaned up when an exception occurs, use a try/finally block. Close the resources in the finally clause: try { conn.Open(); ... } finally { if (null != conn) conn.close; }
Pages • Trim your page size. • Enable buffering. • Ensure debug is set to false. • Optimize expensive loops.
Pages • To trim your page size, you can do one or all of the following: ● Use script includes for any static scripts in your page to enable the client to cache these scripts for subsequent requests:<script language=jscript src="scripts\myscript.js"> ● Remove characters such as tabs and spaces that create white space before you send a response to the client. // with white space <table> <tr> <td>hello</td> <td>world</td> </tr> </table> The following sample table does not contain white spaces. // without white space <table> <tr><td>hello</td><td>world</td></tr> </table>
Pages • If buffering is turned off, you can enable buffering by using the following methods: ● Enable buffering programmatically in a page. Response.BufferOutput = true; ● Enable buffering at the page level by using the @Page directive: <%@ Page Buffer = "true" %> ● Enable buffering at the application or computer level by using the <pages> element in the Web.config or Machine.config file: <pages buffer="true" ...>
Pages • Ensure Debug is set to false: <compilation debug="false" ... /> • To set debug to false at the page level: <%@ Page debug="false" ... %> • When debug is set to true, the following occurs: ● Pages are not batch compiled. ● Pages do not time out. When a problem occurs, such as a problem with a Web service call, the Web server may start to queue requests and stop responding. ● Additional files are generated in the Temporary ASP.NET Files folder. ● The System.Diagnostics.DebuggableAttribute attribute is added to generated code. This causes the CLR to track extra information about generated code, and it also disables certain optimizations.
Iterating and Looping • Avoid repetitive field or property access If you use data that is static for the duration of the loop, obtain it before the loop instead of repeatedly accessing a field or property. The following code shows a collection of orders being processed for a single customer. for ( int item = 0; item < Customer.Orders.Count ; item++ ){ CalculateTax ( Customer.State, Customer.Zip, Customer.Orders[item] ); } Instead: string state = Customer.State; string zip = Customer.Zip; int count = Customers.Orders.Count; for ( int item = 0; item < count ; item++ ) { CalculateTax (state, zip, Customer.Orders[item] ); }
Iterating and Looping • Optimize or avoid expensive operations within loops Identify operations in your loop code that can be optimized. Look for code that causes boxing or allocations as a side effect. The following code causes side effect strings to be created for each pass through the loop. String str; Array arrOfStrings = GetStrings(); for(int i=0; i<10; i++) { str+= arrOfStrings[i]; } To avoid extra string allocations: StringBuilder sb = new StringBuilder(); Array arrOfStrings = GetStrings(); for(int i=0; i<10; i++) { sb.Append(arrOfStrings.GetValue(i)); }
Iterating and Looping • Consider replacing recursion with looping since each recursive call adds data to the stack. Example: Array arr = GetArrayOfStrings(); int index = arr.Length-1; String finalStr= RecurStr(index); string RecurStr(int ind){ if (ind <= 0) return ""; else return (arr.GetValue(ind)+RecurStr(ind-1)); } Rewritten: string ConcString (Array array){ StringBuilder sb = new StringBuilder(); for (int i= array.Length; i>0; i--){ sb.Append(array.GetValue(i)); } return sb; }
Iterating and Looping • Use for instead of foreach in performance-critical code paths since .NET uses an enumerator to provide enhanced navigation through arrays and collections. Instead of: for (int i=0; i<yourControl.Items.Count; i++){ … } Use: foreach (Control ctrl in yourControl) { … }
Additional Resources • Microsoft Application Blocks: http://msdn2.microsoft.com/en-us/library/ms954836.aspx • FxCop: http://www.gotdotnet.com/team/fxcop/ • ASP.Net Analyzer: http://msdn2.microsoft.com/en-us/vstudio/aa718345.aspx
Questions ???