我具有查询数据库的功能
private async Task<IEnumerable<T>)> RunQuery<T>(string sql)
{
using (var conn = new SqlConnection(_connStr))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 300;
await conn.OpenAsync().ConfigureAwait(false);
var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false);
// ... yield return the result from the reader
某些查询需要很长时间才能运行,因此我需要将其取消(这样它将释放数据库锁,等等)。如何实现?
答案 0 :(得分:0)
如对问题的评论中所述,请使用带有CancellationToken
的重载,因为这样您就可以通过用于生成令牌的CancellationTokenSource
触发取消请求。
通过将以下代码放入Windows Forms应用程序来模拟长时间运行的任务,可在工作中看到此结果:
CancellationTokenSource _cts = new CancellationTokenSource();
bool _started = false;
private async void button1_Click(object sender, EventArgs e)
{
if (!_started)
{
_started = true;
using (var conn = new SqlConnection(_connStr))
using (var cmd = new SqlCommand("WAITFOR DELAY '00:00:30'", conn))
{
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 300;
await conn.OpenAsync().ConfigureAwait(false);
var reader = await cmd.ExecuteReaderAsync(_cts.Token).ConfigureAwait(false);
MessageBox.Show("Done");
}
}
else
{
_cts.Cancel();
}
}
单击表单上的按钮一次将触发对数据库的请求,第二次请求将其取消。确实会引发异常,然后需要对其进行适当处理: