2

I'm of the belief that you should never have to use Task.Run for any operation in .net core web context. If you have a long running task or CPU intensive task, you can offload it to a message queue for async processing. If you have a sync operation, that has no equivalent async method, then offloading to background thread does nothing for you, it actually makes in slightly worse.

What am I missing? Is there a genuine reason to use Task.Run in a high throughput server application?

JohanP
  • 5,252
  • 2
  • 24
  • 34

2 Answers2

4

Some quick examples:

  1. A logging system where each worker thread can write to a queue and a worker thread is responsible for dequeuing items and writing them to a log file.

  2. To access an apartment-model COM server with expensive initialization, where it may be better to keep a single instance on its own thread.

  3. For logic that runs on a timer, e.g. a transaction that runs every 10 minutes to update an application variable with some sort of status.

  4. CPU-bound operations where individual response time is more important than server throughput.

  5. Logic that must continue to run after the HTTP response has been completed, e.g. if the total processing time would otherwise exceed an HTTP response timeout.

  6. Worker threads for system operations, e.g. a long running thread that checks for expired cache entries.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Thanks for your reply! Can't we for number 3 just use `IHostedService` for scheduling tasks? Number 4 for me is the one that I have thought of too as why in day to day I would probably do. For number 6, would we need `Task.Run` there or should we do this? (https://stackoverflow.com/questions/45013054/asp-net-core-long-running-task) – JohanP Jul 10 '18 at 03:53
  • These are examples to answer your question. If you have questions about any of the particular items, please post separate questions. I’m sorry but I’m not gonna spend time going over the entire list in detail with you. – John Wu Jul 10 '18 at 04:30
  • 1
    I wasn't expecting you to go over anything with me, it was more a reply to your examples as to why we still don't need Task,Run. – JohanP Jul 10 '18 at 04:37
  • 1
    5. is pretty stupid in an ASP.NET Core context. When you run something after the response is completed, you just ask for trouble, since scoped services get disposed at the end of the request but if your code still runs, it yells for `ObjectDiposedException`. 4 doesn't apply, the question is about high-throughput server application. – Tseng Jul 10 '18 at 11:35
  • 1
    @Tseng What I find stupid is a solution is search of a problem, which is the context here. The point of the list is to show situations that async + single-threaded sync code cannot solve, not to provide complete and correct solutions to imaginary problems. – John Wu Jul 10 '18 at 16:42
3

Just to backup your belief:

Do not: Call Task.Run and immediately await it. ASP.NET Core already runs app code on normal Thread Pool threads, so calling Task.Run only results in extra unnecessary Thread Pool scheduling. Even if the scheduled code would block a thread, Task.Run does not prevent that.

This is the official recommendation/best practice from Microsoft. Although it doesn't point out something you might have missed, it does tell you that it is a bad idea and why.

Jan Suchotzki
  • 1,406
  • 12
  • 24