【问题标题】:MySQL is blocking GUI with awaitMySQL 用 await 阻塞 GUI
【发布时间】:2020-05-30 10:52:04
【问题描述】:

我正在使用一个在运行长 SQL 语句时应该显示的对象;我使用 XAML 中的布尔值和数据绑定来触发它;

<window>
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />
    </Window.Resources>
        <Controls:ProgressRing x:Name="PRwaiting" Visibility="{Binding Path=isBusy,Converter={StaticResource BoolToVis}}"/>
</window>

在代码隐藏中;

public async void DoSomething()
    isBusy = true;
    await LongRunninSQL();
}

private async Task<bool> LongRunninSQL() {
//The isBusy ProgressRing object is visible when I use this delay with a normal SQL statement
//await Task.Delay(3000); 


//Yet, the GUI is blocked when this is executed. (and no progressring is displayed)
string SQL = $"select benchmark(9999999, md5('when will it end?')) AS Benchmark";
Collection = await DBC.SelectAsync(SQL);

DBC.SelectAsync:

        public async Task<DataTable> SelectAsync(string query)
        {
            var dataTable = new DataTable();

            if (this.OpenConnection() == true)
            {
                using (MySqlCommand cmd = new MySqlCommand(query, connection))
                {

                    cmd.CommandText = query;

                    using (var dataReader = await cmd.ExecuteReaderAsync())
                    {
                        dataTable.Load(dataReader);

                        //close Data Reader
                        dataReader.Close();

                        //close Connection
                        this.CloseConnection();

                        //return list to be displayed
                        return dataTable;
                    }
                }
            }
            return dataTable;
        }

即使使用了 await 和 async,我如何才能找出 SQL 语句冻结 GUI 的原因?

【问题讨论】:

    标签: c# mysql wpf async-await


    【解决方案1】:

    这是MySql.Data 长期存在的问题:它们包含异步 ADO.NET 端点,但同步实现。不幸的是,这是你“只需要知道”的事情,因为 AFAIK 除了一些 Stack Overflow 问题外,它没有在任何地方记录。

    由于您正在开发 GUI 应用程序,因此使用 Task.Run 将是可接受的解决方法:

    public async void DoSomething()
    {
      isBusy = true;
      await Task.Run(() => LongRunninSQL());
    }
    

    或者,您可以卸载 MySql.Data 并将其替换为 MySqlConnector,它使用真正的异步实现。

    【讨论】:

    • 感谢您的回答; MySQLconnector 是否有缺点,或者它是使用 MySQL 的“新方式”?我只使用 MySQL.Data 因为我真的不知道还有其他方法
    • @Fimlore: MySql.Data 是官方的,所以我喜欢它。但是它们不支持真正的异步,因此我不喜欢它。我会考虑它们并使用看起来最好的一个;没有“正确答案”。
    • @Fimlore MySqlConnector 不是“官方的”,如果这对您很重要的话。但它修复了 Oracle 的 MySql.Data 的许多错误和“陷阱”(例如这个),因此您可能会发现它值得切换:mysqlconnector.net/tutorials/migrating-from-connector-net/…
    • 感谢您的建议;改变轻而易举;我所要编辑的是我如何打开连接,因为它不喜欢重用已经打开的连接..
    猜你喜欢
    • 2012-02-20
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多