Handle exception when using Task.Run() in UI constructor

I have a constructor that call Task.Run() like this:

public MyPage() {
    Task.Run(() => {
        MyHeavyCpuMethod();
    });
}

Here, MyPage() is the constructor of a UI component, and I don't want MyHeavyCpuMethod() to run on my UI thread, so I offload it with Task.Run() in a fire-and-forget fashion since I don't really care when MyHeavyCpuMethod() finishes.

However, this way if MyHeavyCpuMethod() throws, I can't handle the exception that is in the returned Task.

How can I do error handling in this case?

Jon Skeet
people
quotationmark

One option is to use async/await... which doesn't work with a constructor, but which can work in a static method:

public static async Task<MyPage> CreateInstance()
{
    await Task.Run(...);
    // Anything else asynchronous you want to use
    return new MyPage();
}

And then assuming you're using this from an async method, you can just use:

MyPage page = await MyPage.CreateInstance();

That way, if the CPU-bound task fails, you won't even get to the constructor call. The constructor call itself is expected to be fast here, as that will be on the UI thread (as you want it to be).

An alternative to this, you could potentially store the task returned by Task.Run as a field in the page, and then await that post-construction... using the normal async exception handling approaches.

people

See more on this question at Stackoverflow