调用异步函数的不同方式

本文关键字:方式 异步 函数 调用 | 更新日期: 2023-09-27 18:10:08

我正在尝试制作一个可以异步写入SQL的日志类。我想我已经在Logger课上实现了。我的问题是,我发现有两种方法来调用异步函数,哪一个(如果有的话)是正确的方式或更明智的方式?

我有以下类称为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异步并等待任务,第二个选项只是返回任务。如果你不需要该方法是异步的(例如,因为你在await之后有一些逻辑),它也不必是。

如果您调用async方法而不调用await,它将简单地返回一个任务而不是执行该方法。

//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框架方法

中的约定。