Timigen
Timigen

Reputation: 1025

Different ways to call an asynchronous function

I am attempting to make a logging class that can asynchronously write to SQL. I think I have the implementation in the Logger class. My issue is I have discovered there are two ways to call the asynchronous function, Which (if any) is the correct way or more sensible way?

I have the following class called Logger:

public class Logger
 {
    public Logger() { }

    public async Task<int> RecordAsynchSQL(string sid, string lid, string action) 
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString)) 
        {
            using (SqlCommand cmd = new SqlCommand("MyDB..audit_raw_save", conn)) 
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("@sid", SqlDbType.VarChar, 50).Value = sid;
                cmd.Parameters.Add("@lob_id", SqlDbType.VarChar, 50).Value = lid;
                cmd.Parameters.Add("@action", SqlDbType.VarChar, 500).Value = action;

                await cmd.Connection.OpenAsync();
                await cmd.ExecuteScalarAsync();
            }
        }

        return 1;
    }
}

I have tried the following methods to call this method:

Task task = Task.Run(() => logger.RecordAsynchSQL(id, lid, action))

And:

Task task = Task.Run(async () => await logger.RecordAsynchSQL(id, lid, action));

Upvotes: 2

Views: 116

Answers (2)

i3arnon
i3arnon

Reputation: 116548

Both of your options are pretty much equivalent and unnecessary.

All you need to do to call an async method is simply just call it, and await the returned task:

var task = logger.RecordAsynchSQL(id, lid, action);
var result = await task;

Or:

var result = await logger.RecordAsynchSQL(id, lid, action);

When you use Task.Run you are offloading to a ThreadPool thread. That hurts performance and should be avoided if it isn't necessary.


The difference between your two options is that the first makes the lambda async and awaits the task and the second simply returns the task. If you don't need the method to be async (for example because you have some logic after await) it doesn't have to be.

Upvotes: 4

William Barbosa
William Barbosa

Reputation: 4995

If you call an async method without await it'll simply return a task instead of executing the method.

//This returns a task that can be consumed later
Task task = logger.RecordAsynchSQL(id, lid, action);
//This returns the integer result
int result = await logger.RecordAsynchSQL(id, lid, action);
//As you can see, you can wait for the previously created task
int result2 = await task;

As a side note, consider ending your method name with "Async", as this is a convention in .net framework methods

Upvotes: 1

Related Questions