C# CancellationToken 如何与 SqlConnection.OpenAsync(token) 一起使用?

标签 c# asynchronous

我正在尝试将 CancellationToken 与 SqlConnection.OpenAsync() 结合使用来限制 OpenAsync 函数所花费的时间。

我创建了一个新的 CancellationToken 并将其设置为在 200 毫秒后取消。然后我将它传递给 OpenAsync(token)。然而,此功能仍可能需要几秒钟才能运行。

查看文档我真的看不出我做错了什么。 https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.openasync?view=netframework-4.7.2

这是我使用的代码:

    private async void btnTestConnection_Click(object sender, EventArgs e)
    {
        SqlConnection connection = new SqlConnection(SQLConnectionString);
        Task.Run(() => QuickConnectionTest(connection)).Wait();
    }

    public async Task QuickConnectionTest(SqlConnection connection)
    {
        CancellationTokenSource source = new CancellationTokenSource();
        CancellationToken token = source.Token;
        source.CancelAfter(200);

        ConnectionOK = false;

        try
        {
            using (connection)
            {
                await connection.OpenAsync(token);

                if (connection.State == System.Data.ConnectionState.Open)
                {
                    ConnectionOK = true;
                }

            }
        }
        catch (Exception ex)
        {
            ErrorMessage = ex.ToString();
        }
    }

当 CancellationToken 在 200 毫秒过去时抛出 OperationCanceledException 但它只是等待时,我期待 OpenAsync() 提前结束。

为了复制这个,我做了以下事情:

  • 运行代码:Result = Connection OK
  • 停止 SQL 服务
  • 运行代码:挂起连接长度。超时

  • 最佳答案

    你的代码对我来说似乎是正确的。如果这没有按预期执行取消,则 SqlConnection.OpenAsync 不支持可靠取消。取消是合作的。如果它没有得到适当的支持,或者存在错误,那么您将无法得到任何保证。

    尝试升级到最新的 .NET Framework 版本。您也可以尝试 .NET Core,它似乎领先于 .NET Framework。我关注 GitHub 存储库,发现了多个与异步相关的 ADO.NET 错误。

    您可以在超时后尝试调用 SqlConnection.Dispose()。也许那行得通。您也可以尝试使用同步 API (Open)。也许那使用了不同的代码路径。我相信它不会,但值得一试。

    如果这不起作用,您需要编写代码,以便即使连接任务尚未完成,您的逻辑也会继续。假装它已经完成,让它在后台徘徊,直到它自己完成。这可能会导致资源使用量增加,但可能没问题。

    无论如何,请考虑在 GitHub corefx 存储库中以最少的重现(例如 5 行连接到 example.com)打开一个问题。这应该可以正常工作。

    关于C# CancellationToken 如何与 SqlConnection.OpenAsync(token) 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54150514/

    相关文章:

    Java Akka 的 ActorRef 与预定问题异步

    javascript - 通过在客户端上调用多个 Meteor 方法避免回调 hell

    AngularJS。在服务中解决 promise 后如何更新指令?

    c# - MVC5 的嵌套布局

    c# - 规范的 HTTP POST 代码?

    reactjs - 如何根据同一周期的状态有条件地运行 useEffect

    c# - IntPtr.Zero 是否等同于 null?

    c# - 创建一个 "portable".exe(没有安装程序)

    c# - WPF MVVM 登录凭据

    c# - Polly 未正确处理 OracleExceptions ORA-03113 和 ORA-03114