简体   繁体   English

如何取消Ado.Net异步调用?

[英]How to cancel Ado.Net async calls?

I have a function to query database 我有查询数据库的功能

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

Some queries take a long time to run and I need to enable it to be cancelable (so it will release the database locks, etc). 某些查询需要很长时间才能运行,因此我需要将其取消(这样它将释放数据库锁等)。 How to implement it? 如何执行呢?

As mentioned in the comments on the question, use the overload that takes a CancellationToken , as you can then trigger cancellation of the request via the CancellationTokenSource used to generate the token. 如对问题的评论中所述,请使用带有CancellationToken的重载,因为您随后可以通过用于生成令牌的CancellationTokenSource触发对请求的CancellationTokenSource

Simulating a long running task by dropping the following code into a Windows Forms app, shows this at work: 通过将以下代码拖放到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();
    }
}

Clicking the button on the form once triggers the request to the database and a second time requests that it be cancelled. 单击表单上的按钮一次将触发对数据库的请求,第二次请求将其取消。 This does cause an exception to be thrown which then needs to be handled appropriately: 这确实会引发异常,然后需要对其进行适当的处​​理:

取消数据库请求引发的异常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM