0 Comments

We’re working with a Windows 8.1 Store App where we need to know the physical screen size of the display. Here’s some simple code which seems to do the trick in most cases:

            var width = Window.Current.Bounds.Width * (int)DisplayProperties.ResolutionScale / 100;
            var height = Window.Current.Bounds.Height * (int)DisplayProperties.ResolutionScale / 100;

            var dpi = DisplayInformation.GetForCurrentView().RawDpiY;

            var screenDiagonal = Math.Sqrt(Math.Pow(width / dpi, 2) +
                        Math.Pow(height / dpi, 2));

            return screenDiagonal.ToString();

Please note that the DPI will return 0 if you have two displays in duplicate mode: http://msdn.microsoft.com/en-us/library/windows/apps/windows.graphics.display.displayinformation.rawdpix

0 Comments

Windows Phone caches web requests aggressively. We’ve all seen a case where the first request to the web server works as expected but then the following requests fail to return up-to-date data. Instead of just adding the timestamp to the request URL, you can fix this issue on the server side.

Background

Here’s a simple app next to Fiddler which demonstrates the problem. The app issues a web request with every button click:

        private async void DoRequest_OnClick(object sender, RoutedEventArgs e)
        {
            var client = new WebClient();
            await client.DownloadStringTaskAsync("http://adafy.com");

            requestCount += 1;

            this.RequestCount.Text = requestCount.ToString();
        }

First, a screenshots where user has clicked the button the first time:

image

And here’s what happens when she clicks the button the second time:

image

As you can see from the Fiddler, no request is sent to the server: Windows Phone returns the web request’s response from the cache.

The most often seen solution to this is to add a timestamp to the URL, this way bypassing the Windows Phone’s caching mechanisms. Example:

image

The requested URL changes every time, this way bypassing Windows Phone’s caching.

Solution

All this is because of the web request’s response headers.Make the server return the following Cache-Control header and your app will work exactly as you want:

Cache-Control: public, max-age=15, must-revalidate

Where max-age defines how long (in seconds) your Windows Phone app will cache the request.

By changing the headers you can configure how the app behaves. For example:

  1. You can force your app to make a fresh request every time (set max-age to 0).
  2. You can set exact caching (in seconds) for the requests.

Setting the headers on ASP.NET MVC

ASP.NET MVC offers multiple ways of configuring cache-control header. For example you can set the header on every action:

Response.Headers.Set("Cache-Control", "public, max-age=15, must-revalidate");

Or you can create a filter which is automatically executed after each request. The following StackOverflow questions show multiple solutions:

http://stackoverflow.com/questions/7087859/how-do-i-add-site-wide-no-cache-headers-to-an-mvc-3-app

http://stackoverflow.com/questions/9234044/asp-net-mvc-and-ie-caching-manipulating-response-headers-ineffective

Setting the headers on Azure Blob Storage

If you use Azure Blob Storage as your app’s backend, you can set caching for each blob using the blob.SetProperties-method:

            var blob = container.GetBlockBlobReference(file);
            blob.UploadText(content);

            blob.Properties.CacheControl = string.Format("public, max-age={0}, must-revalidate", (int)cacheAge.TotalSeconds);
            blob.Properties.ContentType = contentType;

            blob.SetProperties();

0 Comments

I blogged about VB.NET’s IIF-statements few years ago. As I mentioned back then, they are a handy way to shorten the code and to make it more readable but also a great way to introduce subtle bugs into our systems. Here’s the part 2 two that blog post, dealing with If statements and nullable variables.

Given the following VB.NET code:

        Dim amount = 100
        Dim newAmount As Integer? = If(amount = 100, Nothing, 50)

        Console.WriteLine("New value: {0}", newAmount)

With the first glance it’s quite obvious that the app will print “New value: ” as we’re setting newAmount to nothing. But when run, here’s what we see:

image

Strange. NewAmount isn’t “nothing” as we thought, it’s actually 0. To correct the issue, we have to cast the “nothing” to nullable integer:

        Dim amount = 100
        Dim newAmount As Integer? = If(amount = 100, CType(Nothing, Integer?), 50)

        Console.WriteLine("New value: {0}", newAmount)

And this time we get the desired output:

image

8 Comments

There’s two ways to use storage in Windows Phone 8 apps:

  • Isolated Storage
  • Windows.Storage

So which one should you use? My recommendation: Windows.Storage.And why? Because Isolated Storage isn’t thread safe.

When the app is small and there’s no 3rd party libraries, you can create a wrapper over the Isolated Storage which uses locking to make sure that only one thread can access the Isolated Storage. But as soon as you add a third party library, you’ll lose control: If the library uses Isolated Storage, it will bypass the locking mechanism you have created inside your storage wrapper.

So, in order to save yourself from random exceptions and strange data losses, prefer Windows.Storage over Isolated Storage.

2 Comments

Sometimes when you try to debug a Windows Phone app through emulator with Visual Studio, you may encounter the following error:

A specified communication resource (port) is already in use by another application

image

One possible reason for this is that Visual Studio tries to debug an app which isn’t deployedto the emulator.

For example, if you set the startup project like this:

image

And then through Visual Studio’s Configuration Manager you don’t check the “Deploy” for this particular project:

image

You will get the error when launching the debugger.