In this post we will see a simple code fragment that can be used to detect memory leaks (more specific objects that are not cleaned by the garbage collector) and we will do it in the context of an interesting memory leak that can be created when using event delegates.
The memory leak with event delegates
Suppose you have an application in WPF with a single window that presents some money values in a specific currency (say EURO). At a specific instance you may have more than one such windows open.
Now a requirement comes that defines that you need to be able to change the currency (say from euro to dollar) and have this change be reflected immediately to any currently open window displaying the money value. One easy way to tackle this is shown in the following figure:

The "settings" object is static with a static property "Currency" with the current currency and an event called "OnCurrencyChanged" that is fired when the currency is changed. The "Window" class ("window1" nad "window2" objects) defines a method "currencyChanged". When a window is opened it attaches the "currencyChanged" method to the "OnCurrencyChanged" event. This method will be called whenever the event is fired and will be responsible for converting the money values in the windows. Let's see some code for that. First the "settings" class:
public static class settings
{
public static event Action OnCurrencyChanged;
public static void ChangeCurrency(string newCurrency)
{
//...
if (OnCurrencyChanged != null)
OnCurrencyChanged(newCurrency);
}
}
The code for the window with the money values has the "currencyChanged" method:
public partial class MoneyWindow : Window
{
public MoneyWindow()
{
InitializeComponent();
}
public void currencyChanged(string newCurrency)
{
// Change the view to reflect the change here
}
}
The initializer of the window with the money values will be as follows:
MoneyWindow dlg = new MoneyWindow();
dlg.Show();
settings.OnCurrencyChanged += dlg.currencyChanged;
Which in other words defines that when the window is created it will be listening to the "OnCurrencyChanged" event.
And you have your memory leak right there! Even if you close the window in some time, the event you have attached still keeps it "connected" to your application and therefore it will never be garbage collected. Just for a reminder, the objects are destroyed by the garbage collector when there are no other objects pointing to them. But in this case you have an "implicit" connection with the event. If you execute the demo application (here) you will see that opening and closing the window keeps consuming more and more memory which never gets freed (it helps to have the "Task Manager" open to test that). The solution is simple and it just requires you to unsubscribe from the event with "-=" when the window is closed. But say you are in a large application you are not sure whether an object gets garbage collected or not and wanna check that then what can you do?.
Detecting memory leaks
Or better checking whether an object will get garbage collected. Implement in your project a class like the following:
public static class MemoryLeak
{
public static WeakReference Reference { get; private set; }
public static void CheckObject(object ObjToCheck)
{
MemoryLeak.Reference = new WeakReference(ObjToCheck);
}
public static void IsItDead()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (MemoryLeak.Reference.IsAlive)
Debug.WriteLine("Still here");
else
Debug.WriteLine("I 'm dead");
}
}
The code creates a weak reference to an object. The "weak reference" means that while it keeps a reference to the object this does not prevent the garbage collector from cleaning it (in other words this reference does not count in terms of collecting the object when not referenced). So we create the reference and then by calling "IsItDead" we just force the GC to collect any unneeded objects. If the object in question still persists then we have a memory leak.
For our example above, when we create the window we create a weak reference to the window object. Then we create a button that calls the "IsItDead" method. If we do not have a memory leak then the method should return "Still here" while the window is open and "I 'm dead" a while after the window is closed.
You can download the demo project here
In this post we will explore a generic way of handling unpredicatble errors/lost connectivity in our Windows 8 Apps developed with HTML5 and
Javascript. The two requirements we need to tackle are as follows:
- There is a chance that while our application is running, internet connectivity will be lost. We need to know when this happens in
order to inform the user and possibly handle the problem while preserving application state.
- Unpredicatble errors may occur that will cause a general exception. We need to "catch" those errors, informing the user with a
generic (and apologetic) error message and maybe transmit some useful details about the error to a service we have implemented for this purpose.
Handling internet connectivity problems
First we need a way to verify whether the app has connectivity to the internet. This can be done by using the following function:
utilities.isConnected=function() {
var connectivity=Windows.Networking.Connectivity;
var profile = connectivity.NetworkInformation.getInternetConnectionProfile();
if (profile) {
return (profile.getNetworkConnectivityLevel() != connectivity.NetworkConnectivityLevel.internetAccess);
}
else {
return false;
}
}
The function returns true if the application is connected to the internet and false if it is not. This function can be used in a page whenever the
user clicks on a button or in general an action will be invoked that will trigger a WinJS.xhr or something similar and if it returns false the application should prevent the action from
being executed.
The same can be applied when the user navigates to a page that uses the internet in its "onload" event. But in this case what can you do? Meaning
that the user reaches the page/pages that to fetch data "on load", the connection is down so nothing is fetched and then you need to display a button or something or start a timer that
checks the coneectivity and at some time refreshes the page.
Or you could easily and with a few lines of code handle this case generally as follows: The idea is to use a "nointernet" page
and lead the user there when you detect there is no internet. Then you prompt the user to hit the back button or a button you provide when he feels that the connection has been re-
established. So let's see how this works:
First you need to implement a simple "no internet" page. A snapshot of the page is given below.
In the navigator.js file that handles the navigation, we find the _navigated function that is called whenever a user goes from one page to another
before the load event of the new page and we add the following lines at the top:
_navigated: function (args) {
if (args.detail.location.indexOf("nointernet") == -1 && !utilities.isConnected()) {
nav.navigate("/pages/nointernet/nointernet.html");
return;
}
// ...rest of the function
This means that if we are not already in the "nointernet" page and the internet connectivity has been lost instead of going wherevere the user
chose to go we navigate to the "nointernet" page.
In the "nointernet" page the click event handler of the "Retry" button calls WinJS.Navigation.back();
And this is it. With just a few lines of code you can handle with dignity all connectivity issues that may occur during the user's navigation in all
application pages
Handling unpredicatble erros
The second requirement states that the app should be able to handle unpredictable errors in a graceful manner. We will follow a similar approach
with an "error" page dedicated just for that.
The "Retry" button with just call again WinJS.Navigation.back() hoping that ther error was temporar. But how do we send the user to this page upon
an unpredictable error?
We just need to handle the onerror event in the default.js file (or in some other file) as follows:
app.onerror = function (customEventObject) {
var errorMessage = '';
var errorName = '';
if (customEventObject.detail.error) {
errorMessage = customEventObject.detail.error.message;
errorName = customEventObject.detail.error.name;
}
else {
errorMessage = customEventObject.detail.exception.message;
errorName = 'Exception';
}
var optionsObject = { errName: errorName, errMsg: errorMessage };
nav.navigate("/pages/error/error.html", optionsObject);
return true;
}
Now if you want to take this one step further and have some private service listening for those errors (so you know what your users are
experiencing) you can implement a simple ASP.MVC 3 application (empty), add just one controller (say ServicesController) with a single Action called Error:
public class ServicesController : Controller
{
public JsonResult Error(string errName,string errMsg)
{
// Store the data in the database or whatever
return Json(new {stored=true},JsonRequestBehavior.AllowGet);
}
}
You host this service in the net and then in the "error" page (on ready event) you write something similar to the following:
ready: function (element, options) {
element.querySelector("#buttonRetry").onclick = function (ev) {
WinJS.Navigation.back();
}
WinJS.xhr({ url: 'http://localhost:10162/Services/Error?errName=' +
options.errName + '&errMsg=' + options.errMsg }, function (data) {
});
}
Now you have a personal bug reporting tool so you know the problems that occur for each one of the deployed application instances out there.