更新时间: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:
cmd.Dispose()
(根据设计或事故)直到 cmd.ExecuteNonQueryAsync
能够完成其工作后才返回-这意味着您实际上仅从 cmd.Dispose $ c $返回c>在 cmd.ExecuteNonQueryAsync
之后;在这种情况下,代码可以工作,但是您不能从await / async中受益;
cmd.Dispose()
被执行阻止 cmd.ExecuteNonQueryAsync()
完成的方式;在这种情况下,代码将无法正常工作; cmd.Dispose()
(by design or accident) does not return until cmd.ExecuteNonQueryAsync
was 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;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.