Sunday, June 15, 2014

Lessons Learned in Windows Mobile (Windows CE and .NET Compact Framework 2.0) Development Part 1

It has been months since I joined a company whose products revolve around Windows Mobile 5 and we are using .NET Compact Framework 2.0 and C# for the development. So far, the product is still far from over, but in agile sprint point of view, the product is getting better and better everytime we present it to the stakeholders at the end of sprint iterations. As the lead developer of the project, here are the things me and the team had learned so far:

  • GUI toolkit. The best I had seen is Resco Mobile Toolkit. I had tried demo versions of different toolkit and this one stands out visually. In my initial assessment, Resco's UI Components are slow in terms of rendering. But I accidentally discovered that by issuing a Control's Refresh method, the rendering is accelerated. Plus, compared to a competitor toolkit, this has so many additional things (WebDav, Audio, Zip, etc). The license fee outweights the advantages. We are currently using this in our project.
  • Protobuf-net. DotNET  CF 2.0 doesn't provide binary serialization by default. I am currently using this heavily on my project. https://code.google.com/p/protobuf-net/
  • Using SQL CE and .NET Datatables. One of my colleague insisted to create an SQL CE based database on the extracted data from 3 CSV files which is just a couple of size (around 350KB combined size). After the implementation, our system - which has a total of 64MB - got 32MB of free RAM and there is some performance hit when the database is being queried (SQL connection always open). We tried to open and close the connection, but a further performance hit was experienced although the memory consumption is much lower. I tried to use a memory-persisted Datatable and our system got 42MB of free RAM and no performance hit (queries using DataTable's select method). I did a further research and SQL CE takes around 8MB or more once it is instantiated and left open. I perceived that if the data is around byte or just kilobytes in size, it may be a good idea to just use in-memory Datatables. But if the database is very large, let's say in order of 100MB, it is not a good idea to use in-memory Datatables and stick with the file-based database instead. So as a lesson learned, we try to weigh things first and communicate with each other often especially if a sprint product backlog item is in design stage.
  • Architecture. Whether we are a fan of MVC (Model View Controller) or MVP (Model View Presenter), there must always be a separation of concern between those things. After doing a trial run for the MVC and MVP architectures, I am currently sticking with MVP in Passive View. If one is not careful though, the Presenter tends to become a God object (which is one of the known problems of Mediator pattern). If we tend to solve it aggressively, we could end up having lots of classes and interfaces, and too many passing of interface parameters and in the end creating more confusion - which sometimes do more harm than good.
  • Pinvoke. Pinvoker is a very good Visual Studio plug-in (and it is free!). http://www.pinvoker.com/Downloads.aspx
  • Pinvoke with structure arrays. I had problems Pinvoking at structure with another structure array inside. Based from my research, there is no known work around for this and instead I created a Python script to generate elements for this problem.
These are the important things that I had learned so far. The databases part is the most important one. When I previously developed database-based projects on PC, I don't usually care on the memory size of the SQL object. But developing in a constrained environment, we always tend to look on every details which may affect the performance or the memory.