Using Async/Await with long running, progress reporting non-blocking methods run Asynchronously via Task.Run

Young chinese man doing malabarism, with porcelain plates.

As an amateur coder, I find the world of Async/await and Tasks a little baffling. Most examples I found used pre-existing Async methods such as HttpClient.ReadAsStringAsync However, if you tried to implement them with your own long running, synchronous methods, particularly ones which are required not to block the main thread and also to provide update of progress, things seem to get tricky fast. This all came to a head when I was trying to write a helper class around one of DotNetZip’s methods which unfortunately aren’t asynchronous. The code:

The key mechanics are the Task.Run and the various async/await components. Firstly, the Task.Run runs the PerformUnzip Method on a separate thread. However, this on its own would mean the methods would run asynchronously and the code would just continue on the main thread. Initially, I just placed:

Task.Run(() => PerformUnzip(archiveFile.FullName, targetDirectory.FullName, unzipProgress))

in the Constructor. You couldn’t just put an await in front of it in the constructor. The trick was to put an intermediary method ‘between’ Unzip and PerformUnzip and have this perform the call there instead:

await Task.Run(() => PerformUnzip(archiveFile.FullName, targetDirectory.FullName, unzipProgress));

Another thing of interest to Task newbies like me is the Progress Type – this is used much like the old ReportProgress of the old BackGround worker days. Hopefully it’ll be clear how it’s used here (although the implementations a little complex due to the ExtractProgressEventArgs class being a little convoluted).

In your main routine, you just call it thus:

await unzipper.Unzip();

(ahhhh.. satisfying!) 😏

About stigzler 47 Articles
Chief crook and wattle bosher.

Be the first to comment

Leave a Reply

Your email address will not be published.