我遵守了代码的和平:
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;
}
我如何识别,捕获的异常是由操作取消引起的。在这种情况下,ExecuteNonQuery抛出异常,错误代码为0x80131904,但这是非常普遍的异常,可能由多种原因引起。错误消息如下所示:{“当前命令发生严重错误。结果(如果有)应该被丢弃。\ r \ n用户取消操作。”}
除了解析错误信息之外,我没有看到任何选项......有什么想法吗?
由于
PS。是的,我知道asyncronyc操作的取消命令可能不是最好的主意,因为对于.NET 2.0,MSDN上有警告,但对于.NET 4.0,这个警告被删除了。当我从另一个线程调用cancel方法时,我也不喜欢另一个实现,因为对我而言,它会使代码更加困难
答案 0 :(得分:2)
似乎没有语言环境不敏感的机制可以捕获此错误。 HResult 0x80131904 is just COR_E_SqlException
。错误始于TdsParser.cs:2332,没有任何唯一属性。它几乎与:2759 - Unknown Error和:3850 - Unexpected Collation完全相同。
以下是我想出的错误解决方案:
选项1:打破了“不要使逻辑语言环境敏感”的良好建议
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");
}
}
选项2:假定在发出取消通知后,其他严重的本地生成错误都不重要
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");
}
}
答案 1 :(得分:-1)
所以你应该做下一步:
我希望这可以帮到你
答案 2 :(得分:-2)
您可以在catch块中检查异常消息,以查找用户取消了哪个操作:
try
{
//your code
}
catch (SqlException ex)
{
if (ex.Message.Contain("Operation cancelled by user"))
{
//Do something here
}
}