
My struggles with the Universal Windows Platform (UWP) continue. A key contributor: Asynchronous file operations and pop-ups.
It used to be so simple: A Windows application is basically a message pump, so you just wired it up to respond to events. Button clicks. Menu selections. The application closing. That kind of thing.
Yes, how you did that wiring changed as Microsoft’s frameworks evolved and improved. To many, classic Visual Basic was a high point, thanks to its visual Rapid Application Development (RAD) capabilities. But Windows Forms provided the same benefits, and with a more sophisticated language, C#. And Windows Presentation Foundation (WPF) added resolution- and DPI-independence and wonderful XAML language for declaratively creating user interfaces in code. There were always challenges moving forward, and missing functionality from the past, but the advantages of doing so always outweighed the problems.
Until the Universal Windows Platform (UWP), that is. Debuting with Windows 8 in 2012 as Metro, UWP (as we call it now in Windows 10) does provide advantages over past frameworks, though the biggest—cross-device compatibility with Windows 10-based PCs, phones, Xbox consoles, Surface Hubs, HoloLens headsets, and more—never emerged as a viable solution, and any apps that do take advantage of this capability suffer from the common least-common-denominator issue that plagued most cross-platform solutions of the past.
If you want to amuse yourself, visit Microsoft’s What’s a Universal Windows Platform (UWP) app? page. It never actually says what a UWP is. Instead, it provides a laundry list of platform advantages, like security, Microsoft Store distribution, and the like.
Here’s what UWP really is: A mobile apps platform, just like iOS and Android. The key difference between UWP and those platforms is the diversity of device types that it supports. Which, again, is not a real-world advantage for most developers. I can’t speak definitively to the sophistication of UWP vs. iOS or Android, but what I can speak to is how well this platform works for those wishing to build a modern application that will run on the Windows 10 desktop. It’s mixed. There’s good and there’s bad.
To its credit, Microsoft did start adding more and more desktop-oriented features to UWP when it became clear that its “One Windows” strategy, as this cross-device thing was called, had failed. I wrote about some of this previously, like its support for the traditional menus that are common in desktop apps, and more compact layouts that facilitate more professional-looking solutions.
But as a superset to WPF, a more modern way to create apps, UWP comes up short in many areas.
One of the biggest issues I’ve faced is UWP’s asynchronous task requirements. It’s meant to be sophisticated, where you can fire off an asynchronous task and the application doesn’t just halt until that task completes. It sounds good on paper. But it is a huge problem in two areas that are key to .NETpad: File operations and responding to user input via a pop-up window, or similar UI.

By file operations, I mean things like open, reading, and saving text files, which are obviously key features for a text editor. There is no instance in which doing any of that asynchronously makes sene for .NETpad, and that’s true whether you’re displaying an Open or Save/Save As dialog, in which case the underlying application logic should ground to a halt until the dialog is closed, or when you’re doing a UI-less Save operation; saving a text file is so fast that the application UI never gets hung up anyway.
But in UWP, all file operations are asynchronous and there is no way to disable it. Yes, there are reasons for this, which include protecting the underlying OS from the app. But for my application, this makes no sense. It needs to see the file system and interact with files. You know, like a normal app.
UWP (or C#) does apparently provide a way to defer asynchronous tasks, meaning that you can actually cause the app to wait until an operation completes. But this is poorly documented and I have not figured out how to implement such a thing.
Asynchronous operations on dialog boxes and other secondary windows is likewise pointless for this application. Consider the Save prompt, which in UWP I’m implementing with something called a Content Dialog that has “Save,” “Save As,” and “Cancel” buttons. Obviously, I don’t want the application under this modal dialog doing anything until the user selects one of those buttons. But there’s no way to override it. You just have to work around it. And that’s dumb, because this kind of thing was easy in VB, WinForms, and WPF. It’s basic stuff. (Async event handlers also cannot return a Boolean value, which means I need to rethink how I’ve handled many of these things in the past as well.)
I’ve spoken of my love of XAML. That still holds, but there is a creeping growth in XAML code in this app—because of its many panels, flyouts, content dialogs, and so on—that makes the app harder to understand and manage. There is likewise a creeping growth in C# code, especially in custom methods, to accommodate all that UI too. Just propping up the UI is getting overwhelming, and I haven’t even implemented core features like Find/Replace yet.

I also struggled to implement user settings correctly, for reasons that are hard to describe. But here’s one example. When you save font settings, you use code like the following:
settings.Values["MyFontSize"] = Convert.ToDouble(TextBox1.FontSize); settings.Values["MyFontItalic"] = TextBox1.FontStyle.ToString();
Pretty straightforward. MyFontSize is a double and MyFontItalic is a string. But MyFontFamily is also a string. And if this worked as it did in WPF, you could use code like the following to save that setting:
settings.Values["MyFontFamily"] = TextBox1.FontFamily.ToString();
But that saves the fully-qualified name of the font’s parent’s object type … for some fricking reason:
Windows.UI.Xaml.Media
Which is not a font. So for that one setting only, I need to use this:
settings.Values["MyFontFamily"] = TextBox1.FontFamily.Source.ToString();
It took a while to figure out why my fonts weren’t working properly. And the reason, I’ve come to understand, is … because f$%^ you, that’s why. Seriously, it’s impossible to overstate how much time I’ve wasted trying to figure out why things that just worked and were easy in WPF do not work without serious rewriting in UWP. It’s a frustration. I’ve spent days—literally—on individual parts of this app, things like saving and loading settings, as noted, but also implementing various flyouts and panels, and content dialogs, and more.
Anyway, I have gotten a lot done. It’s tough going. But I’ll keep going.
With technology shaping our everyday lives, how could we not dig deeper?
Thurrott Premium delivers an honest and thorough perspective about the technologies we use and rely on everyday. Discover deeper content as a Premium member.