调用异步函数的不同方式
Different ways to call an asynchronous function
我正在尝试创建一个可以异步写入 SQL 的日志记录 class。我想我已经在 Logger
class 中实现了。我的问题是我发现有两种调用异步函数的方法,哪种方法(如果有的话)是正确的方法还是更明智的方法?
我有以下 class 称为 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;
}
}
我试过以下方法来调用这个方法:
Task task = Task.Run(() => logger.RecordAsynchSQL(id, lid, action))
并且:
Task task = Task.Run(async () => await logger.RecordAsynchSQL(id, lid, action));
您的两个选项几乎相同且不必要。
调用异步方法所需要做的就是简单地调用它,然后等待返回的任务:
var task = logger.RecordAsynchSQL(id, lid, action);
var result = await task;
或者:
var result = await logger.RecordAsynchSQL(id, lid, action);
当您使用 Task.Run
时,您正在卸载到 ThreadPool
线程。这会损害性能,如果没有必要,应该避免。
您的两个选项之间的区别在于,第一个使 lambda 异步并等待任务,第二个只是 returns 任务。如果你不需要方法是异步的(例如因为你在等待之后有一些逻辑)它不一定是。
如果您在没有 await
的情况下调用 async
方法,它只会 return 一个任务而不是执行该方法。
//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;
作为旁注,请考虑以 "Async" 结束您的方法名称,因为这是 .net 框架方法中的约定
我正在尝试创建一个可以异步写入 SQL 的日志记录 class。我想我已经在 Logger
class 中实现了。我的问题是我发现有两种调用异步函数的方法,哪种方法(如果有的话)是正确的方法还是更明智的方法?
我有以下 class 称为 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;
}
}
我试过以下方法来调用这个方法:
Task task = Task.Run(() => logger.RecordAsynchSQL(id, lid, action))
并且:
Task task = Task.Run(async () => await logger.RecordAsynchSQL(id, lid, action));
您的两个选项几乎相同且不必要。
调用异步方法所需要做的就是简单地调用它,然后等待返回的任务:
var task = logger.RecordAsynchSQL(id, lid, action);
var result = await task;
或者:
var result = await logger.RecordAsynchSQL(id, lid, action);
当您使用 Task.Run
时,您正在卸载到 ThreadPool
线程。这会损害性能,如果没有必要,应该避免。
您的两个选项之间的区别在于,第一个使 lambda 异步并等待任务,第二个只是 returns 任务。如果你不需要方法是异步的(例如因为你在等待之后有一些逻辑)它不一定是。
如果您在没有 await
的情况下调用 async
方法,它只会 return 一个任务而不是执行该方法。
//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;
作为旁注,请考虑以 "Async" 结束您的方法名称,因为这是 .net 框架方法中的约定