WPF Asynchronous Wait Cursor using Task Parralel Library

While working on a WPF application, I had a need to show the wait cursor while performing a long running operation. You would expect the code to look as follows:

System.Windows.Input.Cursor previousCursor = someWindow.Cursor; someWindow.Cursor = System.Windows.Input.Cursors.Wait; try { LongRunningOperation(); } finally { someWindow.Cursor = previousCursor; }

However, I didn't want the long running process tying up the UI thread. I needed to run the long running operation on its own thread. I decided to use the Task Parallel Library (TPL) to help.

System.Windows.Input.Cursor previousCursor = someWindow.Cursor; someWindow.Cursor = System.Windows.Input.Cursors.Wait; System.Threading.Tasks.Task.Factory.StartNew(() => { LongRunningOperation(); }).ContinueWith((t) => { someWindow.Dispatcher.BeginInvoke(new Action(() => someWindow.Cursor = previousCursor)); });

Note that I had to use Dispatcher.BeginInvoke since the ContinueWith code is running on another thread.

After writing this code, I quickly realized that I could use this functionality in multiple places. Therefore, I came up with the following helper method:

code> using System; using System.Threading.Tasks; using System.Windows.Input; ... public Task ShowWaitCursorWhile(this FrameworkElement element, Action action) { Cursor previousCursor = this.Owner.Cursor; element.Cursor = Cursors.Wait;

return Task.Factory.StartNew(() => { action(); }).ContinueWith((t) => { element.Dispatcher.BeginInvoke(new Action(() => element.Cursor = previousCursor)); }); } ...

This seemed like useful code, so I figured I'd throw it out here so that others may benefit from it. Since I am doing Model-View-View Model (MVVM) development, I will probably try to find a way to abstract this into a separate utility that can then be mocked out when testing. That way my view model won't be coupled to the view or its particular cursor/wait implementation.

This article is part of the GWB Archives. Original Author: Jacob L. Adams

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.