c# - 为什么 DbConnection.OpenAsync(CancellationToken) 的默认实现是同步的?

标签 c# .net task-parallel-library

我正在阅读 documentation for DbConnection.OpenAsync(CancellationToken)并找到以下代码段:

The default implementation invokes the synchronous Open call and returns a completed task. The default implementation will return a cancelled task if passed an already cancelled cancellationToken. Exceptions thrown by Open will be communicated via the returned Task Exception property.

现在,如果我的网络连接不稳定/速度慢,并且使用的数据库提供程序没有覆盖 DbConnection.OpenAsync(CancellationToken)(即,我使用的不是 System.Data.SqlClient),如果我将其放入 UI Button 的事件处理程序中,例如:(假设代码,未经测试)

async void button1_Clicked(object sender, EventArgs e)
{
    using (var connection = MyProviderFactory.CreateConnection())
    {
        button1.Text = "Opening…";
        connection.ConnectionString = _SomeString;
        try
        {
            await connection.OpenAsync(default);
            button1.Text = "Opened successfully!";
        }
        catch (Exception ex)
        {
            button1.Text = ex.Message;
        }
    }
}

根据我引用的文档,如果连接需要足够长的时间才能完成,如果提供者没有覆盖默认实现,我的表单将在建立连接时显示为“(未响应)”。无论底层数据库提供程序如何,为了防止这种情况发生,我不妨执行 await Task.Run(async () => await connection.OpenAsync());。为什么默认实现是这样的?在不编写提供程序感知代码的情况下,如何知道何时需要 Task.Run()

最佳答案

您的 await Task.Run(async () => await connection.OpenAsync()) 不会在同一个线程中执行 connection.OpenAsync(),但是connection.OpenAsync()connection.Open() 依赖线程本地状态是完全合理的。他们可能而且通常应该注意 Transaction.Current , 例如。如果 .NET Framework 在后台线程中静默执行 connection.Open(),有些人会得到非常错误的结果。

关于c# - 为什么 DbConnection.OpenAsync(CancellationToken) 的默认实现是同步的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34911914/

相关文章:

c# - 获取 exe 的所有可能命令行参数的列表

c# - 矩形角度属性

c# - 发送文件后关闭 ModelPopup

c# - 内联 MultiBinding 未按预期工作

c# - 从多个线程写入 bool 变量在 C# 中安全吗?

c# - 存储/检索位 C# 的最佳方式

c# - 如何使用 Azure AD 生成具有角色定义的 token

c# - .net 中的类是私有(private)的还是内部默认的?

c# - 连接调试器时,带有 Task.Run 的代码会更改输出

task-parallel-library - 将CancellationToken传递给Task.Factory.StartNew()的目的是什么