Sti*_*son 3 c# asp.net ado.net asynchronous
在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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是我是否应该对cmd.ExecuteNonQueryAsync()语句进行等待,或者如果可以省略等待,因为我基本上只需要做一次即发即弃.
只是触发并忘记异步操作是不行的 - 它可能会因异常而失败,并且在这种情况下你几乎肯定想做某事(通知用户/重试/爆炸).(此外,如果有人使用特定选项,则任务中的异常最终会导致该过程失效).
另外:谁负责关闭连接?
编辑:为了使连接关闭的问题更加清晰,我将使用try/ 重写using语句finally(我知道它不是完全相同的IL,但它足够接近,看看问题出在哪里) - 在这种情况下,代码大致变为:
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();
}
Run Code Online (Sandbox Code Playgroud)
你可以看到cmd.Dispose()之后被称为cmd.ExecuteNonQueryAsync().这怎么可行?我看到两种可能性:
cmd.Dispose()(通过设计或事故)不能返回,直到cmd.ExecuteNonQueryAsync能够完成它的工作 - 这意味着你实际上只能从cmd.Dispose之后返回cmd.ExecuteNonQueryAsync; 在这种情况下,代码可以工作,但是你不会受益于await/async;cmd.Dispose()以防止cmd.ExecuteNonQueryAsync()完成的方式执行; 在这种情况下,代码不起作用;在这两种情况下,程序都是错误的 - 您需要或者await调用Wait()任务以确保它的行为正确.
| 归档时间: |
|
| 查看次数: |
3152 次 |
| 最近记录: |