Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non awaitable as "fire & forget" - is it safe to use? [closed]

Tags:

c#

async-await

We need to write some logs in our code.
The logs are being written via a network request which logs some info (the logger is an Http-API module), But we don't want to break the whole flow if there's an exception in the API.

I don't to use Task.Run for this kind of operation, because it's bad.

But then I thought about non-awaitable-inline-function , something like this :

private static readonly HttpClient client = new HttpClient();

void Main()
{

    Console.WriteLine(1);
    async Task LogMe()
    {
        var response = await client.PostAsync("http://www.NOTEXISTS.com/recepticle.aspx", null);
        var responseString = await response.Content.ReadAsStringAsync();
        //response.EnsureSuccessStatusCode(); // I don't need this here
        Console.WriteLine("error");
    }

    //some code
    LogMe();
    //some code
    Console.WriteLine(3);

}

output:

1
2

Question:

Is it a viable solution for logging in a "fire-and-forget" mode?
What if I create objects inside this inline method, when are they going to be GC'ed?

like image 966
Royi Namir Avatar asked Dec 26 '19 07:12

Royi Namir


1 Answers

I don't to use Task.Run for this kind of operation, because it's bad.

It's important to recognize/specify context for this kind of statement. Task.Run is bad on ASP.NET. It's perfectly OK to use in a GUI app on the client side.

We need to write some logs in our code.

I strongly recommend using an established logging library. Most of them work by using an in-memory queue that is (synchronously) written to by your code, and which is continually processed by a background thread. This is a pattern that is well-established.

Is it a viable solution for logging in a "fire-and-forget" mode?

One of the problems with "fire and forget" is that you don't know when there are errors. The established logging libraries all have some kind of system for dealing with errors communicating with the logging backend; the code you posted will just ignore them.

What if I create objects inside this inline method, when are they going to be GC'ed?

Conceptually, async methods act as GC "roots" as long as they are going to continue executing in the future. So local objects will be GC'ed when the method completes.

like image 51
Stephen Cleary Avatar answered Sep 21 '22 11:09

Stephen Cleary