2015-08-26 16 views
2

Я пытаюсь создать класс ведения журнала, который может асинхронно писать в 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)); 
+0

Если вы ищете «огнь и забыть» стиль звонков - http://stackoverflow.com/questions/12803012/fire-and-forget-with-async-vs-old-async-delegate. Обратите внимание, что все такие механизмы теряют контекст исходного потока, то есть для ASP.Net вы не сможете получить доступ к «HttpContext.Current» для регистрации контекста трассировки. Если возможно, предпочитайте регулярный 'await', как показано в [i3arnon's answer] (http://stackoverflow.com/a/32234168/477420) –

ответ

4

Оба ваших вариантов в значительной степени эквивалентны и не нужны.

Все, что вам нужно сделать, чтобы вызвать метод асинхронного просто назвать его, и ждать возвращаемые задачи:

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

Или:

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

При использовании Task.Run вы разгрузка в a ThreadPool нить. Это ухудшает производительность, и его следует избегать, если это не необходимо.


Разница между вашими двумя вариантами является то, что первым делает лямбда асинхр и ожидает задачи и второй просто возвращает задачу. Если вам не нужен метод async (например, потому что у вас есть логика после ожидания), это не обязательно.

1

Если вы вызываете метод 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 методов каркасных