Reputation: 1025
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
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
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