在执行异步触发时忘记await语句并忘记使用ado.net写入数据库,在C
在asp.net应用程序中,我想尽可能高效地登录数据库.我使用基本的ADO.NET写入日志数据库,我想做这个异步,所以这是我做的:
using (var conn = new SqlConnection(_connectionString)) { using (var cmd = new SqlCommand("INSERT INTO dbo.Logs (TimeStamp,ThreadId,Level,Message,Exception) VALUES (@TimeStamp,@ThreadId,@Level,@Message,@Exception)",conn)) { cmd.Parameters.AddWithValue("@TimeStamp",DateTime.UtcNow); cmd.Parameters.AddWithValue("@ThreadId",Thread.CurrentThread.ManagedThreadId); cmd.Parameters.AddWithValue("@Level",level); cmd.Parameters.AddWithValue("@Message",msg); cmd.Parameters.AddWithValue("@Exception",ex == null ? "" : ex.ToString()); conn.Open(); cmd.ExecuteNonQueryAsync(); } } 现在我的问题是我是否应该对cmd.ExecuteNonQueryAsync()语句进行等待,或者如果可以省略等待,因为我基本上只需要做一次即发即弃. 解决方法
只是触发并忘记异步操作是不行的 – 它可能会因异常而失败,并且在这种情况下你几乎肯定想要做某事(通知用户/重试/爆炸). (此外,如果有人使用特定选项,则任务中的异常最终会导致该过程失效).
另外:谁负责关闭连接? 编辑:为了使连接关闭的问题更加清晰,我将用try / finally重写using语句(我知道它不是完全相同的IL,但它足够接近,看看问题出在哪里) – 在这种情况下,代码大致变为: SqlConnection conn; try { conn = new SqlConnection("connString"); SqlCommand cmd; try { cmd = new SqlCommand("INSERT INTO dbo.Logs (TimeStamp,conn); cmd.AddParameters(); conn.Open(); cmd.ExecuteNonQueryAsync(); } finally { if (cmd != null) cmd.Dispose(); } finally { if (conn != null) conn.Close(); } 您可以看到在cmd.ExecuteNonQueryAsync()之后立即调用cmd.Dispose().这怎么可行?我看到两种可能性: > cmd.Dispose()(按设计或意外)直到cmd.ExecuteNonQueryAsync能够完成其工作才会返回 – 这意味着您实际上只能在cmd.ExecuteNonQueryAsync之后从cmd.Dispose返回;在这种情况下,代码可以工作,但是你不会受益于await / async; 在这两种情况下,程序都是错误的 – 您需要等待或在任务上调用Wait()以确保它的行为正确. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |