So you've got this long running application that gradually takes over all the memory on the computer that it's running on. You've got a resource leak somewhere; but how do you track it down?
Task Manager should be your first stop in determining if your application has a problem with leaking memory. After you've started Task Manager and switched to the Processes tab, go to the View | Select columns menu choice. The dialog box that pops up gives you a list of columns you can add to the display, seven of which have labels beginning with "Memory." The first five (all but the two containing the word "Paged") can provide useful insight to what your application is doing with memory. If you see, for instance, a process that has its Peak Working Set constantly increasing, it's a clue that the process is in trouble.
More
Posted by Peter Vogel on 08/04/20113 comments
Somehow, in the course of our June Toolapalooza feature (17 Free Tools for Visual Studio), I missed a bunch of freebies from Telerik. Telerik has made well over a dozen free tools available -- I lost count -- and they all look pretty cool. It's worth noting, these are not limited-period trials or significantly crippled software. If you're willing to forego support, for instance, you can apparently get Telerik's ASP.NET MVC extensions for free.
More
Posted by Peter Vogel on 07/26/20114 comments
While DataSets hold a lot of data, sometimes you want to keep track of information about the DataSet itself. You could store information about the dataset in some variable (e.g. the last time you checked the DataSet for changes) but it makes sense to me to store that information with the Dataset itself through its extended properties.
To add an extended property to a DataSet, you go the DataSet's ExtendedProperties collection and add a name and a value. This example adds a property called LastChecked to the ExtendedProperties collection with the current date and time:
More
Posted by Peter Vogel on 07/19/20112 comments
One of the best things about .NET is that virtually everything you do in Visual Studio generates some text in a file. This means that, when you need to make a change to several places in your code, you can often make that change with a global Find and Replace. However, the typical developer's scenario is to (a) do a global find-and-replace and then (b) rebuild the application to find out what got broken -- because, sadly, a global find-and-replace often changes too much.
More
Posted by Peter Vogel on 07/12/20110 comments
One of the most frustrating error messages that you can get when debugging your application is "File not found" when loading an assembly (or just instantiating a new class). This message means that, for some reason, .NET couldn't find the DLL with the class you needed. If the reason for the problem isn't obvious from the information provided (and it usually isn't) there is a tool that will give you some more insight: the Assembly Binding Log Viewer (fuslogvw.exe).
More
Posted by Peter Vogel on 07/05/20114 comments
By default, Visual Studio supports XHTML 1.0 Transitional, which dates from 2000. HTML has changed since then and you may want to access some newer version. In fact, with all the buzz HTML5 is getting you might be interested in trying it out, which means you'd like to have Visual Studio stop whining at you when you use HTML5 elements and attributes. IntelliSense support would be nice also.
Service Pack 1 for Visual Studio 2010 helps by adding some IntelliSense and validation support for HTML5 to the versions of HTML that Visual Studio supports. But the default remains XHTML 1.0 Transitional from 2000. You can change that.
More
Posted by Peter Vogel on 06/28/20113 comments
This tip is for C# developers only, unfortunately -- but it's the easiest way in the world to create an iterator. An iterator is any method that returns the "next item" in a series. The issue with an iterator is that you have to return a value when called and then pick up at the "next item" when called again.
The simplest iterator in the world is one that just counts from zero on up. In this example, for instance, x would first be set to 0 and then 1 and then 2 and then... you get the picture:
int res;
foreach (int i in Counter())
{
res = i;
}
Implementing that Counter method is easy if you use yield: Just insert the word "yield" at the start of your return statement to return the value and then pause your method at that statement until the next time it's called. When your method is called, your code will continue on from the statement following the yield statement.
The only wrinkle is that the method must appear in a method that's part of some iterator interface (e.g. IEnumerable). That means, to use the yield statement in the easiest way possible (and, when you're talking about the yield statement, you're aiming for "easiest way possible") you need to declare your method's return type as IEnumerable and call your method inside a foreach block. A version of the Counter method that would go from 0 to 2 would look like this:
public System.Collections.IEnumerable Counter()
{
yield return 0;
yield return 1;
yield return 2;
}
Each time the Counter method is called, the yield return statement will return the value and then wait to be called again before it will go on to the next statement.
A more complicated version would count up from 0 to the largest possible value that an int supports:
public System.Collections.IEnumerable CounterInfinite()
{
int i = 0;
while (i < int.MaxValue)
{
yield return i;
i += 1;
}
}
But the principle remains the same: Whenever your code is called, "yield return" something and then, in the next line of code, go on to get the "next one." If, in a Customers object, you wanted to create a property called Orders that lest a developer loop through all of the Orders for a the customer, you could use the yield keyword. In the property's getter, you would retrieve a DataSet and loop through the rows, returning an Order object created from the row at each yield return.
Here's similar code using LINQ to keep it short. The yield return inside the foreach loop returns an Order object and then waits to be called again before going through the loop to get the next Order:
public IEnumerable<Order> Orders
{
get
{
northwndEntities dc = new northwndEntities();
var res = from o in dc.Orders
where o.CustomerID == this.CustomerId
select o;
foreach (Order o in res)
{
yield return o;
}
}
}
A developer can now process your collection with code like this:
foreach (Order o in cust.Orders)
{
//do something with an order
}
Posted by Peter Vogel on 06/20/20118 comments
In our June Toolapalooza issue (
17 Free Tools for Visual Studio
), we reviewed some of the best and most useful free tools for Visual Studio. One of those tools was smtp4dev, which allows you to quickly check the results of any email that you send from your application -- very useful in testing. But, as I noted in the article, I found smtp4dev to be... well, quirky, let’s say.
More
Posted by Peter Vogel on 06/14/20110 comments
Sometimes you get null or Nothing passed to parameters for methods in your application. Sometimes that's not OK, but sometimes it is -- especially if you're accepting data from a database. If you're accepting a value parameter (like an integer), you may have been declaring your parameters as object so that you accept nulls. There is a better solution: you can add a question mark to your type declaration to indicate that it's OK to pass a null/Nothing value to that parameter:
More
Posted by Peter Vogel on 06/07/20113 comments
In ASP.NET by using Views inside the MultiView you can, effectively, have several different pages inside a single ASPX file. Here's how to have those "additional pages" appear on your site's menus so that when a user clicks on a menu choice, the user not only goes to the right page but also has the page displaying the right View.
The trick here is to take advantage of a feature of the sitemap. In order to support the SiteMapPath control, each SiteMapNode in the in the sitemap must have a unique URL (or none at all). However that "uniqueness" includes whatever querystring you choose to include in the SiteMapNode's url attribute. There's nothing stopping you from having these two entries in your sitemap:
<siteMapNode url="~/Login.aspx?view=0"
title="Show View 0"
description="Display View 0 in a MultiView"/>
<siteMapNode url="~/Login.aspx?view=1"
title="Show View 1"
description="Display View 1 in a MultiView"/>
While the url attribute in these sitemapnodes point to the same page, they have different querystrings. If the page "MultiViewPage.aspx" has a MultiView on it, then this code in the Page_Load event will (when the user first sees the page) cause the View control specified in the querystring to be displayed:
if (!this.IsPostBack)
{
string pos = this.Request.QueryString["view"];
if (pos != null)
{
this.MultiView1.ActiveViewIndex = int.Parse(pos);
}
}
Posted by Peter Vogel on 05/31/20110 comments
Probably the only developers who care about this are the .NET developers doing Office development and who are upgrading projects to.NET 4. But if you do work with COM objects from code and are ever planning to move your projects up from .NET 3/3.5, this is worth knowing.
PIAs (Primary Interop Assembly) provide the information that supports interoperability between .NET and COM. PIAs for complex COM objects (think: Microsoft Word) are huge and kept in separate, monolithic assemblies. That means that when you use any member on your COM object, the whole PIA is loaded into memory (not to mention that the PIA was one more thing to be distributed).
Upgrading to .NET 4 can give you some significant benefits through the "NoPIA" feature (also called Type Embedding, but "NoPIA" just sounds cooler). With NoPIA, the necessary information to support COM interoperability is embedded into your compiled .NET code. Not only does that reduce the number of components to be distributed, only the parts of the PIA actually required by your application are incorporated into your code. If you only use a small part of a big COM object you could see significant size reductions in your compiled code.
The option is automatically turned on for new Visual Studio 2010 projects, but if you've imported a project from an earlier version of Visual Studio, you'll need to set it yourself. In your References list, select the reference to your COM object. Then, in the Properties window, find the Embed Interop Types property and set it to True.
Posted by Peter Vogel on 05/24/20110 comments
Prior to .NET Framework 4, threading used a locking mechanism that added to the thread overhead. In .NET 4 the locking mechanism is eliminated. On top of that, threading integrates better with garbage collection, reducing the time required to clean up after a thread finished running
Putting those two changes together means that just moving your multi-threaded application to .NET 4 can improve its performance. In addition, there was a bug in prior versions of .NET around aborting threads that issued locks. If you aborted a thread at the wrong time (when a no-operation instruction that was part of the generated IL code was being processed), the lock might never be released. If you've been trying to figure out why your multi-threaded application's performance degrades over time, it's a sign that the upgrade to .NET 4 might not be an optional activity.
More
Posted by Peter Vogel on 05/17/20110 comments