【问题标题】:Different ways to call an asynchronous function调用异步函数的不同方法
【发布时间】:2015-08-27 02:41:13
【问题描述】:

我正在尝试创建一个可以异步写入 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));

【问题讨论】:

  • 如果您正在寻找“一劳永逸”的通话方式 - stackoverflow.com/questions/12803012/…。请注意,所有此类机制都会丢失原始线程的上下文,即对于 ASP.Net,您将无法访问 HttpContext.Current 来记录跟踪的上下文。如果可能的话,更喜欢常规的await,如i3arnon's answer所示

标签: c# .net asynchronous async-await task


【解决方案1】:

您的两个选项几乎相同且不必要。

调用异步方法所需要做的只是调用它,然后等待返回的任务:

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

或者:

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

当您使用Task.Run 时,您正在卸载到ThreadPool 线程。这会损害性能,如果没有必要,应该避免这样做。


您的两个选项之间的区别在于,第一个使 lambda 异步并等待任务,而第二个只是返回任务。如果您不需要该方法是异步的(例如因为您在等待之后有一些逻辑),则不必是。

【讨论】:

    【解决方案2】:

    如果您在没有await 的情况下调用async 方法,它只会返回一个任务而不是执行该方法。

    //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 框架方法中的约定

    【讨论】:

      猜你喜欢
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      • 2017-09-23
      • 1970-01-01
      相关资源
      最近更新 更多