Bloodday
Bloodday

Reputation: 303

The use of Task.Delay to convert synchronous call to async

I have a WPF application that call PrintDialog.PrintVisual() in an async event and the first line is of the event is a call to await Task.Delay(1); to return the control to the UI (show a busy Indicator animation) while the printing process is done.

I have never seen this use of Task.Delay and searching in google I have not found any code that do something like that, so I'm wondering if it is correct use of the function or if there is a better approach.

(i know this question can be Off Topic but i don't know a better place to ask, if you consider there is a better place for this question tell me and I'll take it there)

Edit

this is the code inside the event:

            await Task.Delay(1);
            IsBusy.Visibility = Visibility.Visible;
            BusyIndicator.Header = "Imprimiendo...";
            var printDialog = new PrintDialog();
            if ((bool)printDialog.ShowDialog())
                printDialog.PrintVisual(PrintCanvas, "Iprimiendo Venta " + _vm.Sell.Id);
            IsBusy.Visibility = Visibility.Hidden;
            BusyIndicator.Header = "Cargando...";

Upvotes: 0

Views: 271

Answers (1)

Phil Jollans
Phil Jollans

Reputation: 3759

Using

await Task.Delay(1) 

will make the method async from the point of view of the compiler, but is won't make the operation asynchronous. All it will do is free up the UI thread for 1ms.

To make the operation asynchronous, you can put it into a separate function and start it as a task.

private async Task DoPrint()
{
  IsBusy.Visibility = Visibility.Visible;
  BusyIndicator.Header = "Imprimiendo...";
  var printDialog = new PrintDialog();
  if ((bool)printDialog.ShowDialog())
      printDialog.PrintVisual(PrintCanvas, "Iprimiendo Venta " + _vm.Sell.Id);
  IsBusy.Visibility = Visibility.Hidden;
  BusyIndicator.Header = "Cargando...";
}

private void EventHandler()
{ 
  await DoPrint() ;
}

or you could do the same using a lambda function

private void EventHandler()
{ 
  await Task.Run ( () => 
  {
    IsBusy.Visibility = Visibility.Visible;
    BusyIndicator.Header = "Imprimiendo...";
    var printDialog = new PrintDialog();
    if ((bool)printDialog.ShowDialog())
        printDialog.PrintVisual(PrintCanvas, "Iprimiendo Venta " + _vm.Sell.Id);
    IsBusy.Visibility = Visibility.Hidden;
    BusyIndicator.Header = "Cargando...";
  });
}

However, in your case, you probably only want some of it to be asynchronous.

My guess it that it is only call to pringDialog.PrintVisual() which needs to be asynchronous, so it would be sufficient to start this in a task.

private void EventHandler()
{ 
  IsBusy.Visibility = Visibility.Visible;
  BusyIndicator.Header = "Imprimiendo...";
  var printDialog = new PrintDialog();
  if ((bool)printDialog.ShowDialog())
  {
      await Task.Run ( () => printDialog.PrintVisual(PrintCanvas, "Iprimiendo Venta " + _vm.Sell.Id) ) ;
  }    
  IsBusy.Visibility = Visibility.Hidden;
  BusyIndicator.Header = "Cargando...";
}

Upvotes: 1

Related Questions