UWP and C# tricks and traps #1

Vladimir Akopyan
Quickbird
Published in
5 min readDec 25, 2017

--

Some are obvious, others are treacherous

In ideal world becoming an ‘Android/Windows/whatever’ developer would mean just learning ow they work and how to use them. Unfortunately all platforms have their share of bugs, missing documentation and idiotic design decisions. Some are worse than others — I am looking at you Unity3D — and you have to stub a few toes before you can become proficient with them.
I’ve collected some experience form developing Universal windows apps in C# (who does that, right?)

Toast Notifications Throw Exceptions

In Windows, Toast notifications will throw exceptions and crash your app when they get too large, and that’s not mentioned anywhere in the documentation.

The exception is not thrown when the text it too long for display, it is thrown when the Toast exceeds an arbitrary 5KB size. The only place it’s mentioned is a blog post from 2016. The exception has an HResult 0x803E0115 or 2143420139 in decimal

HResult=2143420139 Message=The size of the notification content is too large.

MapControl

With Windows10 UWP apps we finally got a proper, hardware-accelerated Map UI Element. From my casual testing it’s performance completely outclasses that of professional GIS tools such as ArcMap, QGIS and ArcGis Pro. It can draw a million polygons on a laptop with Intel graphics, while QGIS lags on my desktop with just hundred thousand.

MapIcon cannot be resized

if you add a MapIcon to the map, it will be drawn at it’s native resolution (i.e. if you used a 400px image, it will take 400px on the screen). It cannot be resized in code. This is really dumb.

Place Image on Map and rotate it

You can place any XAML UIelement on the MapControl. It can be placed “on the screen” like a button the top-left corner on the map, or it can be assigned a specific coordinate on the map, like a label for location of a restaraunt.
Overall result is that I found it more practical to use BitmapImage on the MapControl instead of MapIcon because I wanted to resize them as the user zooms out. Rotating them, however, turned out to be quite involved.

MapBillboards fade away

MapBillboards are meant to be used in place of MapIcons when you need the icons to respect map zoom level. However when the user zooms out beyond a certain point, they become transparent and fade-away. This behaviour cannot be configured Ii, for your purposes, this happens too early or too late.

MapModel3D

In Windows Fall Creator’s Update (build 16299) Microsoft has added API to place 3D models to the map. First thing I’ve done is make Uber-style applications for Windows 10. However, ther are two undocumented gotcha’s that can ruin your day.

Loading 3D model Must happen on UI thread

Microsoft provide only an asynchronous method to load the model object.

await MapModel3D.CreateFrom3MFAsync(Object, MapModel3DShadingOption.Smooth);

Usually that’s fine, but sometimes we might want to load it in a constructor, and they cannot await for async methods. One trick to get around that is to push async method onto a seperate task and wait for it in a blocking manner:

var loading = Task.Run(await() => async method());
loading.Wait();

This trick won’t work with this API — MapModel3D 3D can only be loaded by the UI thread. Doing otherwise, when you attempt to add the model to the map you will get an exception.

HResult=-2147467261 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

No Sharing MapModel3D between different MapControls

If you attempt to display the same MapModel3D object on two different MapControls, you will get an exception. This can happen inadvertently if the UI Page with the MapControl is not cached — then every time the user navigates to the UI Page, a new MapControl is created, and the MapModel3D is added.
This can create crashes that are hard to track down as the developer typically has a nuclear-powered beast machine that will never run out of ram, so by default the UI page will always be cached. Then you deploy it to a crappy user laptop and get crashed that you can’t reproduce. Congratulations!

Bindings Depth

Bindings can be “attached” at different ‘depths’, and that’s important for their behaviour. Suppose we have chain of objects: Page has a ViewModel, which in turn contains a Car, which has a Name. We want to display the Car’s Name.

Page.ViewModel.Car.Name

If we rename the Car, the binding should update. But if we replace the Car object? What about replacing the ViewModel object?

Embedding Servers in UWP applications

Why embed a server in a Windows Store application? To collect data from IoT sensors, control robots, seed torrents — you name it.
I tested two MQTT servers — a protocol that works well for IoT, Apps messaging and robots.

GnatMQ

GnatMQ is an MQTT broker written in C#. This MQTT server that is very cross-platform: It supports Windows 10 apps, Windows CE (!) and even .Net Micro Framework for microcontrollers. The library was developed by a Microsoft MVP, and it mostly works well in low-contention scenarios. I ended up as one of the library maintainers. It’s used in several applications — MesQTT app, Quickbird App, for running cloud services and, reportedly, in a couple industrial project based on Windows CE.

DotNetty

DotNetty is a C# port of the super-performant Netty soft-realtime messaging server, originally written in Java. It has replaceable codecs and MQTT is available too. It’s currently used in production for cloud servers and even if it’s lacking documentation it’s probably a better choice for new projects. It has an example for running it inside a UWP application.

EmbedIO

Embedio — tiny pure C# embedded HTTP/ Websocket server. I have not yet had a chance to test it, but it appears worth looking at.

Note on ASP.Net Core

I believe at the moment ASP.net Core is not compliant with UWP Store requirements because at the time it was being developed, .Net Core Networking Stack was not ready so they used P/Invoke for some stuff.

--

--

Making Internets great again. Slicing crystal balls with Occam's razor.