Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Api C# - Task.Factory.startnew vs async

I'm doing logging within my endpoints where the logs are sent to a separate service. I don't want the overhead of sending the logs to a service to affect to service that the client is consuming and I don't care if logs sometimes don't make it. Therefore I've been reading blogs about how to simple fire and forget. I get that CPU intensive tasks should not use async but I don't see how IO related tasks are any different, by IO I mean an endpoint that calls another service, in this case for the purpose of logging.

Also I seem to be getting conflicting views. Some blogs say you should never run anything async because this simply takes one or more threads from the threadpool and it's therefore no different than doing it synchronized.

Microsoft introduced the async and await keywords into .Net 4.5 which they say you should use for the entire endpoint but doesn't this still use one or more threads from the thread pool?. And finally some stackoverflow posts I've read say that it's fine to use Task.Factory.StartNew because .Net will manage it.

Could someone please clarify the above in terms of best practice sending logs to another service as I am very confused.

I'm considering using nlog because of its batching and async features but again I'm not sure if this is the best way. I cannot use something like Hangfire because I don't have sql backend.

Thanks in advance.

like image 633
There is no spoon Avatar asked Feb 06 '23 05:02

There is no spoon


1 Answers

Some blogs say you should never run anything async because this simply takes one or more threads from the threadpool

No, that's absolutely not true. async does not use threadpool threads. (For more information, see my blog post There Is No Thread).

And finally some stackoverflow posts I've read say that it's fine to use Task.Factory.StartNew because .Net will manage it.

Again, not true. StartNew is a dangerous API and should never be used this way. (For more information, see my blog post StartNew Is Dangerous).

Therefore I've been reading blogs about how to simple fire and forget.

Since you "don't care if logs sometimes don't make it", then I'd recommend using HostingEnvironment.QueueBackgroundWorkItem. QBWI will not prevent logs from being lost, but it will do its best to minimize log loss. Just throwing work onto the thread pool using Task.Run (or the outdated and dangerous StartNew) will not even try to minimize loss of logs. Hangfire is for when you need something more robust - if you required your logs to be correct, e.g., for billing or auditing. (For more information, see my blog post on Fire and Forget on ASP.NET).

like image 163
Stephen Cleary Avatar answered Feb 12 '23 10:02

Stephen Cleary