i have following peace of code:
IAsyncResult beginExecuteReader = command.BeginExecuteNonQuery();
while (!beginExecuteReader.IsCompleted)
{
if (controllerTask.CancellationTokenSource.IsCancellationRequested)
{
command.Cancel();
}
Thread.Sleep(100);
}
try
{
result = command.EndExecuteNonQuery(beginExecuteReader);
}
catch (SqlException exception)
{
if (exception.ErrorCode == OperationCanceled)
{
throw new OperationCanceledException();
}
throw;
}
How can i identify, that catched exception is caused by operation cancelation. In this case ExecuteNonQuery throws exception with error code 0x80131904, but it's very general exception which can be caused by many reasons. Error message looks like this: {"A severe error occurred on the current command. The results, if any, should be discarded.\r\nOperation cancelled by user."}
I don't see any options except of parsing of error message... Any ideas?
Thanks
PS. Yeah, i know that Cancel command for asyncronyc operation probably is not the best idea, because for .NET 2.0 there was warning on MSDN, but for .NET 4.0 this warning is removed. And i also don't like another implementations when cancel method is called from another thread, as for me it makes code more difficult
There doesn't seem to be a locale insensitive mechanism to catch just this error. The HResult 0x80131904 is just COR_E_SqlException
. The error is initiated at TdsParser.cs:2332 without any unique properties. It is almost the exact same code as :2759 - Unknown Error and :3850 - Unexpected Collation.
Here are the bad solutions I have come up with:
Option 1: Break the good advice of "don't make logic locale sensitive"
using (var con = new SqlConnection("Server=(local);Integrated Security=True;"))
{
con.Open();
try
{
var sqc = new SqlCommand("WAITFOR DELAY '1:00:00'", con);
var readThread = Task.Run(() => sqc.ExecuteNonQuery());
// cancel after 5 seconds
Thread.Sleep(5000);
sqc.Cancel();
// this should throw
await readThread;
// unreachable
Console.WriteLine("Succeeded");
}
catch (SqlException ex) when (ex.Number == 0 && ex.State == 0 && ex.Class == 11
&& ex.Message.Contains("Operation cancelled by user."))
{
Console.WriteLine("Cancelled");
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
Option 2: Assume that no other severe locally generated error matters after a cancel has been issued
using (var con = new SqlConnection("Server=(local);Integrated Security=True;"))
{
con.Open();
bool isCancelled = false;
try
{
var sqc = new SqlCommand("WAITFOR DELAY '1:00:00'", con);
var readThread = Task.Run(() => sqc.ExecuteNonQuery());
// cancel after 5 seconds
Thread.Sleep(5000);
isCancelled = true;
sqc.Cancel();
// this should throw
await readThread;
// unreachable
Console.WriteLine("Succeeded");
}
catch (SqlException ex) when (isCancelled && ex.Number == 0 && ex.State == 0 && ex.Class == 11)
{
Console.WriteLine("Cancelled");
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With