1

I have a function in c#, call it

public async Task<byte[]> PrintLetter(int Id)    
{
    some code here
    return byte[2125];
}

I was calling it like this: (not sure what the point of the _ is)

 _ = Task.Run(async () => await PrintLetter(cid));

And it was running the print job and working fine. But now I want to assign this PrintLetter() to a variable so I can pass along this byte[] and not just print to printer.

So I wanted to do this:

var files =  await PrintLetter(cid);
return Ok(File(files, "application/pdf", "Letter.pdf"));

But I'm nervous to blindly remove the Task.Run here. Any advice

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Lizi
  • 93
  • 16
  • 1
    Why even use task run? – Daniel A. White Feb 23 '22 at 14:40
  • It was there before my days and running hundreds of thousands of printing. nervous to remove it – Lizi Feb 23 '22 at 14:42
  • Your change would mean that the caller would not return until after your `PrintLetter` method completed. With your original code, it would return immediately since you are not awaiting the `Task.Run`. – Kirk Woll Feb 23 '22 at 14:51
  • Since you are inside a HttpRequest there is no need to a `Task.Run()` - hence you are already in a new thread. So just do `var files = await PrintLetter(cid);` as you want to do. You webapp will perform better, not worse. – Frank Nielsen Feb 23 '22 at 14:55

2 Answers2

2

You could just await the result of the existing Task.Run invocation:

byte[] bytes =  await Task.Run(async () => await PrintLetter(cid));

In this case the async/await can be safely elided from the lambda. The behavior of the code below is identical:

byte[] bytes =  await Task.Run(() => PrintLetter(cid));

Removing the Task.Run is not a no-op though. It might be OK, or it might not. You can check out this question for guidance: await Task.Run vs await

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
1

_ = Task.Run(async () => await PrintLetter(cid));

So, what this is actually doing is a form of fire-and-forget:

  1. The Task.Run ensures that PrintLetter runs outside of the ASP.NET request context. (I'm assuming this is ASP.NET pre-Core).
  2. The _ = discards the task.

So this will execute PrintLetter in a separate thread and not wait for it to complete before returning to the client.

The problem is that fire-and-forget is dangerous. This was never a good solution to begin with. Fortunately, the new requirements (passing back the byte array) means that the fire-and-forget should be removed anyway. This just leaves this:

var files =  await PrintLetter(cid);
return Ok(File(files, "application/pdf", "Letter.pdf"));
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810