Category Archives: windows

Pitfalls mixing PPL+await

Imagine you have a C++/CX codebase with a lot of asynchronous logic written using the classic Parallel Patterns Library (PPL) tasks:

task<void> FooAsync(StorageFolder ^folder) {
  return create_task(folder->TryGetItemAsync(L"foo.txt"))
    .then([](IStorageItem ^item) {
      // do some stuff, cast to a file, etc.

It’s all running on the UI thread, so it’s in a Single Threaded Apartment, and each task in your chain of .then() continuations is guaranteed to also be on the UI thread.

Now, you learn about Microsoft’s relatively new co_await feature, recently accepted in an adapted form in the C++20 spec. So you start using it:

task<void> FooAsyncCo(StorageFolder ^folder) {
  IStorageItem ^item =
    co_await folder->TryGetItemAsync(L"foo.txt");
  // do some stuff, cast to a file, etc.

So far so good: all code inside FooAsyncCo() also runs on the UI thread, nice and clean.

Finally, you integrate a little of this co_await code into your heavily PPL codebase. Helpfully, co_await returns a task, just like your existing async PPL method. Another developer sees that you have a bunch of methods returning task<void> and decides to start building on that API using PPL:

FooAsyncCo().then([]() {
  // more stuff, after coroutine.
  // KABOOM. Running on a threadpool thread, *not* the UI thread.
  // We accidentally busted out of the STA.

Uh-oh. When you mix the two async approaches… things break. And none of the documentation – or honestly anything I’ve read on the web to date – gives any hint of this issue.

Not A Fix

Well… let’s see. The docs do give us one tip: a task chain is only guaranteed to remain inside the Single Threaded Apartment if the chain starts with an IAsyncAction or IAsyncOperation

The UI of a UWP app runs in a single-threaded apartment (STA). A task whose lambda returns either an IAsyncAction or IAsyncOperation is apartment-aware. If the task is created in the STA, then all of its continuations will run also run in it by default, unless you specify otherwise. In other words, the entire task chain inherits apartment-awareness from the parent task. This behavior helps simplify interactions with UI controls, which can only be accessed from the STA.

Asynchronous programming in C++/CX: Managing the Thread Context

Well… TryGetItemAsync does return an IAsyncOperation. That would appear to be the root task in the chain… so coroutines must be treated differently, with the coroutine itself being the root.

Well, what if we tried making the coroutine return an IAsyncAction?

IAsyncAction ^FooAsyncCoAction(StorageFolder ^folder) {
  return create_async([folder]() -> task<void> {
    // KABOOM - this is now out of the apartment.
    IStorageItem ^item =
      co_await folder->TryGetItemAsync(L"foo.txt");
    // do some stuff, cast to a file, etc.
.then([]() {
  // more stuff, after coroutine.
  // ok now!

No dice. Now the coroutine runs off-thread, while the continuation runs correctly on the UI thread.

Two Actual Fixes

With a little more reading, I found Raymond Chen’s blog post about PPL and apartment-aware tasks. That led to this successful solution:

task<void> completed_apartment_aware_task() {
  return create_task(create_async([](){}));

.then([]() {
  // Ok!

This one actually works. By rooting the PPL chain in an IAsyncAction, the rest of the chain retains apartment awareness, and everything stays on the UI thread.

And I’d earlier found a different but more fragile solution:

create_task(FooAsyncCo, task_continuation_context::use_current())
.then([]() {
  // Ok!

While this works, it’s… a bit hard to tell whether the root task, or the continuation, or what-all needs use_current(), and it’s always felt fragile to me. And if it gets called from a threadpool thread, it’s unclear to the caller what happens with use_current().


I’ve got to say… this is a brutal pitfall. Any existing codebase is going to have a lot of PPL tasks in it, and wholesale migration to co_await isn’t going to happen all in one go, at least if there’s any conditional/loop/exception logic in the PPL-based code. Anyone who’s tried to migrate to co_await has probably run into this pitfall.

We haven’t adopted the completed_apartment_aware_task() as a root task throughout our codebase yet, but I’m hopeful that will at least offer a path forward. Just… still quite error-prone.

A Windows to iOS Port

My main activity of 2019 was a port of the Mental Canvas 3D drawing tool from Windows to iOS. About 75% of my effort was user interface code, maybe 15% on graphics and 10% other platform issues.

What’s interesting about our porting approach? Well, it’s just an unusual mix:

  • It’s a UWP (Universal Windows Platform) app. UWP was Microsoft’s effort to modernize Win32 and add iOS mobile paradigms, so it is already touch-centric, relatively sandboxed and has a more mobile-like lifecycle
  • We didn’t use React Native, Flutter, Electron, Xamarin, Qt or even Fuschia’s namesake Pink. We just… wrote some native code. And a lightweight abstraction layer.
  • We completed the porting effort in seven months, with three developers.
  • We stayed with the MVVM architecture that is the norm on Windows. Many iOS developers would call that… exceptionally ok
  • We didn’t use the latest and greatest Swift tools, just plain old C++11 and Objective-C for the most part. We didn’t switch to SwiftUI when it was released half way through our port.

What combination of circumstances led to this approach? Mostly just a real life constraint: a desire to rewrite/redesign as little working code as possible, and keep the codebase’s size down.

  1. Starting Point
  2. UI Framework Choice
  3. Restructuring the UI Thread
  4. Lightweight iOS Bindings
  5. What About SwiftUI?
  6. Incremental Porting
  7. The Upshot: Code Reuse
Continue reading A Windows to iOS Port

Working with XAML Designer 2 (UwpSurface)

In September 2017, Microsoft released a rewritten XAML Designer program within Visual Studio. It’s only enabled for a tiny fraction of apps and got a very quiet launch, so almost no one knows about it. The new version runs as UwpSurface.exe instead of XDesProc.exe and is only enabled for UWP apps targetting Fall Creators Update SDK or newer.
For my app, the new Designer simply broke everything initially. Why? Presumably for technical reasons, it only works with {Binding} and not {x:Bind} – but this was not made at all clear in the launch announcements. UWP developers have been encouraged to use {x:Bind}: it’s compiled, type-safe and faster, and x:Bind functions are the only way to do multibinding. For my 64-bit app, I never got design data or design instances working under XAML Designer (xdesproc), so I relied entirely upon {x:Bind}‘s FallbackValue parameter to preview different modes of my UI – but {Binding} has no equivalent mechanism.
After a lot of tinkering, I’ve finally learned a few important things about the new XAML Designer, and got a usable workflow.

Top Takeaways

  • UwpSurface is much faster and stabler than XDesProc. The dialog above (“Click here to reload the designer”) is largely history.
  • It works for both 32-bit and 64-bit apps (x86 or x64), which is a big step forward
  • Only {Binding} is evaluated; {x:Bind} is completely ignored.
  • DesignInstances (a live ViewModel) can be attached via DataContext or d:DataContext, although the DesignInstance parameter doesn’t seem to work
  • ViewModel code executes, but I don’t see any indication that View code executes, despite discussion to the contrary in Microsoft’s launch blog post
  • For C++/CX apps: due to a bug, only single-class ViewModels (without any C++/CX base classes) work as of Visual Studio 15.8.x. They’re fine in C#.
    (Update Jan. 2019: Visual Studio 15.9 fixed this bug, but ViewModels that implement property change notifications still do not work.)
  • You can attach a debugger and see debug output from your ViewModel, or any exceptions. I haven’t been able to set breakpoints.
  • Update Jan. 2019: Visual Studio 15.9 added support for something I requested in mid-2018: the FallbackValue parameter was added to {Binding}, which makes that an equally viable way to work with XAML Designer. FallbackValue doesn’t work for {x:Bind} in the new Designer.

My strategy for a C++/CX app

  • Stick with {x:Bind} and its functions in most of my code
  • For the few properties that are central to a clean layout (usually about 2-5), use {Binding} and type converters
  • For those properties, build a duplicate “DesignTimeMock” ViewModel class – with no C++/CX base classes – and return the design-time property values there. Most properties can be safely omitted.
  • In the XAML code, define two different DataContexts like this:
        <local:MyViewModel />

    This attaches one ViewModel for runtime, and the mock for design time.

  • Update Jan. 2019: Visual Studio 15.9 now allows a different approach: instead of a DesignTimeMock, you can just have a single DataContext using the “real” view model, but instead change {x:Bind} to {Binding} in the few places where it matters, and then add a FallbackValue parameter to choose the desired value in XAML Designer. The biggest advantage of FallbackValue: you can edit it in place and see it immediately update, without recompiling and relinking the DesignTimeMock view model.

It’s not ideal. But… it’s better than nothing.

Closing Thoughts

Despite the difficulties, I do look forward to further improvements in the XAML Designer. The old version was dated and crash-prone, and a clean slate rewrite was the only reasonable path forward. It’s just going to take some time to reach feature parity with the old version, which will mean some teething pain for “guinea pig” developers like myself.

Asynchronous Best Practices in C++/CX (Part 2)

This is part two in a series of articles on asynchronous coding in C++/CX. See the introduction here.

  1. Prefer a task chain to nested tasks
  2. Be aware of thread scheduling rules
  3. Be aware of object and parameter lifetimes
  4. Consider the effect of OS suspend/resume
  5. Style: never put a try/catch block around a task chain.
  6. References

2. Be Aware of Thread Scheduling Rules

Asynchronous Best Practices in C++/CX (Part 1)

For me, the steepest learning curves with the Universal Windows Platform (UWP) was the use of asynchronous APIs and the various libraries for dealing with them. Any operation that may take more than 50ms is now asynchronous, and in many cases you can’t even call the synchronous equivalent from Win32 or C. This includes networking operations, file I/O, picker dialogs, hardware device enumeration and more. While these APIs are pretty natural when writing C# code, in C++/CX it tends to be a pretty ugly affair. After two years of use, I now have a few “best practices” to share.
C++/CX offers two different approaches for dealing with asynchronous operations:

  1. task continuations using the Parallel Patterns Library (PPL)
  2. coroutines (as of early 2016)

Personally, I vastly prefer coroutines; having co_await gives C++/CX a distinctly C# flavour, and the entire API starts to feel “natural.” However, at my current job we have not yet standardized on coroutines, and have a mix of both approaches instead. And to be fair – despite Microsoft’s assurances that they are “production ready”, I’ve personally hit a few coroutine bugs and they do occasionally completely break with compiler updates.
I’m going to write up my advice in a series of posts, as the examples can be pretty lengthy.

  1. Prefer a task chain to nested tasks
  2. Be aware of thread scheduling rules
  3. Stay aware of object and parameter lifetimes
  4. Consider the effect of OS suspend/resume
  5. Style: never put a try/catch block around a task chain.
  6. References

1. Prefer a Task Chain to Nested Tasks

When writing a series of API calls that need local variables, conditional logic, or loops, it’s tempting to write it as a nest of tasks. But a nest will:

This One Weird Grid Trick in XAML

I recently found a neat XAML user interface trick that I hadn’t seen in my usual resources. Suppose you have:

  • a grid-based responsive user interface that you want to grow/shrink to fit the window
  • suppose it has a fixed width, and each row has a “core” minimum height it needs.
  • then there’s some extra vertical space that you want to sprinkle around
  • you have some priorities – first give row #1 extra space, then row #2 any extra.

XAML makes it easy to do proportional space allocation – e.g., give row #1 two-thirds and row #2 one-third by giving them “2*” and “*” height respectively. But it doesn’t do priorities.
The trick: combine a massive star size with a MaxHeight. That looks like this:

    <RowDefinition Height="1000*" MaxHeight="200" />
    <RowDefinition Height="*" />

Essentially, row #1 gets “first claim” on any extra space, up to a limit of 200 pixels. Any extra space beyond 200 pixels falls over to row #2.

My First XAML Tips for the Universal Windows Platform

I’m a latecomer to Microsoft’s user interface technologies. I never used Windows Framework (WPF) on top of .net and I never used Silverlight on the web. The last year was my first taste of these tools through the XAML framework that is part of the “Universal Windows Platform” (UWP) – that is, the Windows 10 user interface layer (and Win8).
XAML has steadily evolved since the WPF days, and it took a little while to really understand the different major eras of the technology, especially since the UWP flavour of XAML strips out some of the older syntaxes in the name of efficiency on mobile platforms, better error checking at compile-time and code readability and ease-of-use. The technology’s old enough that much of the Google search hits and StackOverflow results are not applicable on the modern UWP platform.

My Tips

So what were a few of my first lessons when using XAML on UWP?
Continue reading My First XAML Tips for the Universal Windows Platform