且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在C#中执行异步触发时省略await语句并使用ado.net忘记写入数据库是否安全?

更新时间:2023-02-20 18:11:02

仅触发并忘记异步操作是不正确的-它可能会因异常而失败,并且您几乎肯定会在这种情况下要做一些事情(通知用户/重试/炸毁)。 (此外,如果有人使用特定的选项,则任务中的异常最终将导致进程中断。)

It is not OK to just fire and forget the async operation - it might fail with an exception, and you nearly certainly want to do something (notify the user/retry/blow up) in that case. (Besides, if someone uses a specific option, an exception in the task will eventually bring down the process).

另外:谁负责关闭连接?

Also: Who is responsible for closing the connection?

编辑:为了更清楚地说明连接关闭的问题,我将使用 try $重写using语句c $ c> / finally (我知道这不是完全相同的IL,但是它足够接近以查看问题出在哪里)-在这种情况下,代码大致变为:

Edit: In order to make the problem of connection closing clearer, I will rewrite the using statements with try/finally (I know it is not the exact same IL, but it is close enough to see where the problem is) - in that case, the code roughly becomes:

SqlConnection conn;
try {
    conn = new SqlConnection("connString");
    SqlCommand cmd;
    try {
        cmd = new SqlCommand("INSERT INTO dbo.Logs (TimeStamp,ThreadId,Level,Message,Exception) VALUES (@TimeStamp,@ThreadId,@Level,@Message,@Exception)", conn);
        cmd.AddParameters();
        conn.Open();
        cmd.ExecuteNonQueryAsync();
    } finally {
        if (cmd != null) cmd.Dispose();
 } finally {
    if (conn != null) conn.Close();
 }

您可以看到 cmd.Dispose() cmd.ExecuteNonQueryAsync()之后被调用。那怎么行?我看到两种可能性:

You can see that cmd.Dispose() is called right after cmd.ExecuteNonQueryAsync(). How can that work? I see two possibilities:


  1. cmd.Dispose()(根据设计或事故)直到 cmd.ExecuteNonQueryAsync 能够完成其工作后才返回-这意味着您实际上仅从 cmd.Dispose $ c $返回c>在 cmd.ExecuteNonQueryAsync 之后;在这种情况下,代码可以工作,但是您不能从await / async中受益;

  2. cmd.Dispose()被执行阻止 cmd.ExecuteNonQueryAsync()完成的方式;在这种情况下,代码将无法正常工作;

  1. Either cmd.Dispose() (by design or accident) does not return until cmd.ExecuteNonQueryAsyncwas able to do its work - meaning that you actually only return from cmd.Dispose after cmd.ExecuteNonQueryAsync; in that case, the code works, but you do not benefit from await/async;
  2. Or cmd.Dispose() is executed in a way that prevents cmd.ExecuteNonQueryAsync() from completing; in that case the code does not work;

在两种情况下,程序都是错误的-您需要等待或对任务调用 Wait()以确保其行为正确。

In both cases, the program is wrong - you need either await or to call Wait() on the task in order to ensure that it behaves correctly.