Simplest Way to Do a Fire and Forget Method in C#

Simplest way to do a fire and forget method in C#?

ThreadPool.QueueUserWorkItem(o => FireAway());

(five years later...)

Task.Run(() => FireAway());

as pointed out by luisperezphd.

Fire and Forget multiple methods in C#

As you're using an Azure function you cannot have true fire and forget as you risk the function terminating before the completion of all the task(s).

However, we don't care for the result of the task, so we need not await each task individually.

System.Collections.Generic.List<System.Threading.Tasks.Task> tasks = new System.Collections.Generic.List<System.Threading.Tasks.Task>();
for (int i = 0; i < 20; i++)
{
tasks.Add(System.Threading.Tasks.Task.Run(() => ApiRef1(i, log));
}
await System.Threading.Tasks.Task.WhenAll(tasks);

This allows all the tasks to fire in parallel, but pause further execution until they're all complete, ensuring the completion of the tasks before the process is terminated.

Proper way to start and async fire-and-forget call?

It depends on what you mean by proper :)

For instance: are you interested in the exceptions being thrown in your "fire and forget" calls? If not, than this is sort of fine. Though what you might need to think about is in what environment the task lives.

For instance, if this is a asp.net application and you do this inside the lifetime of a thread instantiated due to a call to a .aspx or .svc. The Task becomes a background thread of that (foreground)thread. The foreground thread might get cleaned up by the application pool before your "fire and forget" task is completed.

So also think about in which thread your tasks live.

I think this article gives you some useful information on that:
https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx

Also note that if you do not return a value in your Tasks, a task will not return exception info. Source for that is the ref book for microsoft exam 70-483
There is probably a free version of that online somewhere ;P https://www.amazon.com/Exam-Ref-70-483-Programming-C/dp/0735676828

Maybe useful to know is that if your have an async method being called by a non-async and you wish to know its result. You can use .GetAwaiter().GetResult().

Also I think it is important to note the difference between async and multi-threading.

Async is only useful if there are operations that use other parts of a computer that is not the CPU. So things like networking or I/O operations. Using async then tells the system to go ahead and use CPU power somewhere else instead of "blocking" that thread in the CPU for just waiting for a response.

multi-threading is the allocation of operations on different threads in a CPU (for instance, creating a task which creates a background thread of the foreground thread... foreground threads being the threads that make up your application, they are primary, background threads exist linked to foreground threads. If you close the linked foreground thread, the background thread closes as well)
This allows the CPU to work on different tasks at the same time.

Combining these two makes sure the CPU does not get blocked up on just 4 threads if it is a 4 thread CPU. But can open more while it waits for async tasks that are waiting for I/O operations.

I hope this gives your the information needed to do, what ever it is you are doing :)

Simple way to fire-and-forget SignalR calls in netcore 3.1

Would implementing the background work queue functonality detailed on MSDN be the way to go for this? Or am I overthinking it, and I should just discard the Task?

A background queue would give you a "best effort" at running the code. The background queue gives you a way to interact with the hosting process and will delay shutdown if possible to run the code. That said, if it's just not that important, discarding the task is easier.

would the underlying messaging still work the same if I changed things thus

Yes. MethodAsync(); is the same as _ = MethodAsync();. Both lines will call the method and then ignore the returned task. The only difference is the explicit discard (_), which is essentially you telling the compiler "yes, I know this task isn't awaited, and I'm doing it on purpose".



Related Topics



Leave a reply



Submit