Canceling SQL Server query with CancellationToken Canceling SQL Server query with CancellationToken sql-server sql-server

Canceling SQL Server query with CancellationToken


After looking at what your stored procedure is doing, it appears that it is somehow blocking the cancellation.

If you change

RAISERROR (@msg,0,1) WITH NOWAIT;

to remove the WITH NOWAIT clause, then the cancellation works as expected. However, this prevents the InfoMessage events from firing in real time.

You could track progress of the long running stored procedure some other way or register for the token cancellation and call cmd.Cancel() since you know that works.

One other thing to note, with .NET 4.5, you can just use Task.Run instead of instantiating a TaskFactory.

So here's a working solution:

private CancellationTokenSource cts;private async void TestSqlServerCancelSprocExecution(){    cts = new CancellationTokenSource();    try    {        await Task.Run(() =>        {            using (SqlConnection conn = new SqlConnection("connStr"))            {                conn.InfoMessage += conn_InfoMessage;                conn.FireInfoMessageEventOnUserErrors = true;                conn.Open();                var cmd = conn.CreateCommand();                cts.Token.Register(() => cmd.Cancel());                cmd.CommandType = CommandType.StoredProcedure;                cmd.CommandText = "dbo.[CancelSprocTest]";                cmd.ExecuteNonQuery();            }       });    }    catch (SqlException)    {        // sproc was cancelled    }}private void cancelButton_Click(object sender, EventArgs e){    cts.Cancel();}

In my testing of this, I had to wrap ExecuteNonQuery in a Task in order for cmd.Cancel() to work. If I used ExecuteNonQueryAsync, even without passing it a token, then the system would block on cmd.Cancel(). I'm not sure why that's the case, but wrapping the synchronous method in a Task provides a similar usage.