Category Archives: C#

ListBox performance: WinRT vs. WP8 vs. WPF

With the raising popularity of WinRT and WP8 the demand for building complex UIs for managed apps increased significantly . A heavy UI which if not handled properly can lead to poor user experience.

This post will analyze the performance penalties of adding lots of visuals to a ListBox, present the traps of the “easy way” and suggest an alternative for overcoming them.

The problem

Take the following code which creates a collection of items and acts as a ItemsSource to an ListBox. The ListBox renders its items as Rectangles:

 
            
                
                    
                
            
        
        
            
        
        
		
        private void CreateRectangleItems()
        {
            var collection = new ObservableCollection();
            Random random = new Random();
            for (int i = 0; i < 1000; i++)
            {
                collection.Add(new Item()
                {
                    X = random.Next() % (int)this.ActualWidth,
                    Y = random.Next() % (int)this.ActualHeight
                });
            }

            this.DataContext = collection;
        }

       class Item
       {
              public int X { get; set; }
              public int Y { get; set; }
       }
While the code works just fine, it can consume up to 50 MB of memory, which is of course not ideal. Furthermore, the higher the number the items, the higher the memory consumption and the longer the time it takes to generate them e.g. 3000 items can consume more than 100 MB and take 2-3 seconds to be generated. Check out the graph below for a better picture of the behavior. I will call this approach the visuals approach.
Winrt Listbox memory consumption

The solution

Recently I found an efficient way of displaying large number of items while keeping the memory consumption low. Here’s how: replace all the visuals with a single Path visual built based a geometry where you can put as many elements as you want.
I will call this approach the geometry approach and here’s the code for a possible implementation:

            
        
        
            
        
        
			 
        private void CreateGeometryItems()
        {
            var collection = new ObservableCollection();
            var random = new Random();
            var item = new GeometryItem();
            var group = new GeometryGroup()
            {
                FillRule = FillRule.Nonzero
            };

            item.Shape = group;
            for (int i = 0; i < 9000; i++)
            {
                group.Children.Add(new RectangleGeometry()
                {
                    Rect = new Rect(random.Next() % (int)this.ActualWidth,
                           random.Next() % (int)this.ActualHeight, 10, 10)
                });
            }

            collection.Add(item);
            this.DataContext = collection;
        }
This change brings significant memory consumption improvements. Check out the improvements in the chart below (the geometry approach is marked with green)

listbox winrt memory  consumption

After seeing such massive improvements I got curios to see how this technique would work for other platforms like Windows Phone 8 and WPF.

For WP8, the results are pretty much similar, the geometry approach is couple of times faster and less memory expensive than the visuals approach.

listbox wp8 memory consumption

Surprisingly, on WPF the visuals approach is not as memory expensive as is on WinRT or WP. However, the geometry approach is still twice as fast and memory efficient.

listbox wpf memory consumption

Bottom line: if you want to display and manipulate 1000+ visual elements in a ListBox consider the geometry alternative presented above, especially when using WP8 or WinRT.

One more thing ūüôā

I found this technique while I was working on my Win8 app Puzzle Frenzy.

The app is available in Windows Store, check it out and tell me what you think: http://apps.microsoft.com/windows/en-GB/app/puzzle-frenzy/28238e98-ac0f-4a6b-81ea-a31a24a15acf.

You can also give your feedback on app’s review page or on app’s Facebook page http://www.facebook.com/PuzzleFrenzyApp.

Happy coding!

Puzzle Frenzy home page

Puzzle Frenzy Windows 8 app has been released!!!

Hi everyone,

I am pleased to announce that the Puzzle Frenzy app has been release in Windows Store!

Puzzle Frenzy is a realistic jigsaw puzzle game which features over 70 hand-picked images, ideal for puzzle solving.

The game contains several difficulty levels ranging from 16 to 100 pieces.

During the game you can shuffle or sort the pieces and also get hints in case you get stuck.

You can download the app from here: http://apps.microsoft.com/windows/app/puzzle-frenzy/28238e98-ac0f-4a6b-81ea-a31a24a15acf

Puzzle Frenzy home page

Puzzle Frenzy home page

Puzzle Frenzy gameplay in fast forward:

If you have any comments or suggestions check out our  Facebook page or drop us an email at puzzlefrenzyapp@gmail.com.

The page contains details about the game, the story behind some of the images as well as news and updates.

You can also follow us on Twitter  or on Google+

I’m looking forward to your feedback and I hope you enjoy the game!

All the best!

Building Puzzle Frenzy: realistic puzzle pieces

Puzzle Frenzy was built on top of a previous app I wrote for WP7. At that time the app was more simple and the gameplay more limited. The images used, the pieces shape and the difficulty levels were different as well.

For Puzzle Frenzy one of the first things I changed was the puzzle pieces shape.

A great deal of attention was dedicated into making them as familiar to the user as possible.

The WP7 app was using a simple rectangle and four ellipses as connectors for drawing puzzle pieces.

Now I use a Bézier curve with 10 control points for each edge of the piece.

Therefore each Puzzle Frenzy piece is a Bézier curve with 40 control points.

Coming soon: Puzzle Frenzy Windows 8 App

Puzzle Frenzy app for Windows 8 is right around the corner!!!

Puzzle Frenzy home page

Puzzle Frenzy is an realistic jigsaw puzzle for board game lovers of all ages.

The app will feature tons of images and multiple levels of complexity which translate into endless hours of fun puzzle-solving action.

Check out and Like our Facebook page http://www.facebook.com/PuzzleFrenzyApp¬†and I’ll keep you updated with news about the app when it launches.

TDD in WinRT

While experimenting with TDD I run into a pretty nasty exception:

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

However after some investigation I found a very good solution here.

[TestMethod]
public async Task Test1()
{
      await ExecuteOnUIThread(() =&gt;
      {
           WriteableBitmap bitmap = new WriteableBitmap(1, 1);
           Assert.Fail();
      });
}

public IAsyncAction ExecuteOnUIThread(DispatchedHandler action)
{
     return CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, action);
}

Happy coding!

Runtime Windows Phone App

My latest app, Runtime for WP7 is here!

RunTime is a FREE stopwatch app for Windows Phone 7.
The stopwatch continues to run in the background even if you lock the screen or leave the app.
The app allows saving laps.
The app shows both the main stopwatch timer as well as the current lap timer.

You can download the app by scanning the following QR code with Bing Vision (Press the Search button on your WP, press “Vision” then point the camera at the scree and follow the link):

Otherwise you can download it by visit the following link:

http://www.windowsphone.com/en-us/apps/e9e7b11c-242e-4d49-b4a9-c828b40f8d2d

1617e241-8731-4adc-aad0-285d534baa2c

I hope you like the app! Enjoy

Testing the Entity Framework 4.0 RIA Services Domain Service

Recently I’ve been working on refactoring and testing a Silverlight project that uses the EntityFramework.

Making all the changes of the auto-generated code in order to test it proved to be a harder task that I initially imagined.

This article summarises my findings and for getting the system ready for testing.

First of all, here is a list of links that helped me:

Testing out the Entity Framework WCF RIA Services Domain Service

WCF RIA Services Part 8 – Testing and Debugging

Testability and Entity Framework 4.0

However, none of these resources fully describe a working solution.

Here is how I finally got it working:

  • Step 1

Create an IUnitOfWork interface that will abstract the ObjectContext object used by your domain Service
Create additional operations the ObjectContext exposes as extension methods (e.g. AttachAsModified<TEntity>)

  • Step 2

Create an InMemoryUnitOfWork inheriting from IUnitOfWork (used for testing)
Create an InMemoryIObjectSet<T> inheriting from IObjectSet<T> (used for testing)

  • Step 3

Create a testing base class EFTestBaseClass for putting all the things together
Create a particular TestHelperClass for testing a particular test

There are additional important tweeks I will highlight in bold during the example.
Example:
Consider the following table in the entity container called NewTechCodeTestingEntities
An automatically generated Domain Service for manipulating it will look something like:

public class DomainService1 : LinqToEntitiesDomainService<NewTechCodeTestingEntities>
 {
 ...
 }

All the methods we are interested in testing will be hosted in this class. But instantiating it for testing will result in all operations being executed against the database. In order to avoid this situation we will have to somehow decouple this class form the EF.

(Step1)

First of we have to create the previously mentioned IUnitOfWork:

public interface IUnitOfWork
 {
 IObjectSet<Book> Books { get; }

ObjectStateManager ObjectStateManager { get; }
 int SaveChanges();
 }

This class abstracts the NewTechCodeTestingEntities.

This way we can create a special constructor for the Domain Service that we can use during testing:

public class DomainService1 : LinqToEntitiesDomainService<NewTechCodeTestingEntities>
 {
 new private readonly IUnitOfWork ObjectContext;

public DomainService1()
 {
 this.ObjectContext = base.ObjectContext;
 }

public DomainService1(IUnitOfWork unitOfWork)
 {
 this.ObjectContext = unitOfWork;
 }

...
 }

It’s important to notice how we created a new ObjectContext filed by using the new operator which either defaults to the base class ObjectContext (used for the production code when you call the parameterless contructor) or sets it to a specified one we create during testing.

An important thing to notice is the use of IObjectSet<Book> instead of ObjectSet<Book>.

The auto-generated file exposes the object in ObjectSet<T> collections.

In order to use the current approach you will have to manually change All the ObjectSet<T> declarations to IObjectSet<T> (Find and replace should do the trick in seconds)

The second thing you will have to do is make the NewTechCodeTestingEntities implement the IUnitOfWork.

The code will therefore look something like this:

public partial class NewTechCodeTestingEntities : ObjectContext, IUnitOfWork
 {
 ...
 }

Notice that these two steps (changing the collection declaration and inheriting from the IUnitOfWork) will have to be performed each time you update your EF model. I find this approach acceptable mostly because it is the only way I got the whole system to work.

Creating the extension methods are needed for keeping the auto generated code working. The only method I needed was AttachAsModified<T>:

public static class Extension
 {
 public static void AttachAsModified<TEntity&gt;(this IObjectSet<TEntity> objectSet, TEntity current, object original) where TEntity : class
 {
 throw new NotImplementedException();
 }
 }

(Step 2)

The following two classes were created for keeping the testing data:

public class InMemoryUnitOfWork : IUnitOfWork
 {
 public IObjectSet<Book> Books
 {
 get;
 set;
 }

public ObjectStateManager ObjectStateManager
 {
 get;
 set;
 }

public int SaveChanges()
 {
 throw new NotImplementedException();
 }
 }

and

public class InMemoryIObjectSet<T> : IObjectSet<T> where T : class
 {
 public InMemoryIObjectSet()
 : this(Enumerable.Empty<T>())
 {
 }

public InMemoryIObjectSet(IEnumerable<T> entities)
 {
 _set = new HashSet<T>();
 foreach (var entity in entities)
 {
 _set.Add(entity);
 }
 _queryableSet = _set.AsQueryable();
 }
 public void AddObject(T entity)
 {
 _set.Add(entity);
 }
 public void Attach(T entity)
 {
 _set.Add(entity);
 }
 public void DeleteObject(T entity)
 {
 _set.Remove(entity);
 }
 public void Detach(T entity)
 {
 _set.Remove(entity);
 }
 public Type ElementType
 {
 get { return _queryableSet.ElementType; }
 }
 public Expression Expression
 {
 get { return _queryableSet.Expression; }
 }

public IQueryProvider Provider
 {
 get { return _queryableSet.Provider; }
 }

public IEnumerator<T> GetEnumerator()
 {
 return _set.GetEnumerator();
 }

IEnumerator IEnumerable.GetEnumerator()
 {
 return GetEnumerator();
 }

readonly HashSet<T> _set;

readonly IQueryable<T> _queryableSet;
 }

If you are interested in finding more about these classes check the links at the beginning of the article.

(Step 3)

public class EFTestBaseClass
 {
 public EFTestBaseClass()
 {
 this.unitOfWork = new InMemoryUnitOfWork();
 this.controller = new DomainService1(unitOfWork);
 }

protected InMemoryUnitOfWork unitOfWork;
 protected DomainService1 controller;
 }

and

public class BooksTestHelper : EFTestBaseClass
 {
 protected IList<Book> books;

protected InMemoryIObjectSet<Book> repositoryBooks;

public BooksTestHelper()
 {
 this.PopulateCatalogueMaster();
 }

public void PopulateCatalogueMaster()
 {
 this.books = CreateCatalogueMasters().ToList();
 this.repositoryBooks = new InMemoryIObjectSet<Book&gt;(this.books);
 this.unitOfWork.Books = repositoryBooks;
 }

public static IEnumerable<Book> CreateCatalogueMasters()
 {
 yield return new Book()
 {
 Id = 1,
 Title = "Madame Bovary",
 Author = "Gustave Flauber"
 };
 yield return new Book()
 {
 Id = 2,
 Title = "The Lady of the Camellias",
 Author = "Alexandre Dumas, fils"
 };
 yield return new Book()
 {
 Id = 3,
 Title = "Notre Dame de Paris",
 Author = "Victor Hugo"
 };
 }
 }

allows us to create the following test:

 

[TestClass]
 public class BooksTest : BooksTestHelper
 {
 [TestMethod]
 public void GetBooks()
 {
 var books = controller.GetBooks();
 // insert test here
 }
 }

The tweaks that helped me get the system working were the observations highlighted in green which on top of the knowledge you get by reading the introduction articles should help you in testing your application.