MySQL блокирует GUI с ожиданием - PullRequest
0 голосов
/ 14 февраля 2020

Я использую объект, который должен отображаться при выполнении длинного оператора 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);

DB C .SelectAsyn c:

        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;
        }

Как узнать, почему SQL оператор останавливает GUI, даже если используются await и asyn c?

1 Ответ

3 голосов
/ 14 февраля 2020

Это давняя проблема с MySql.Data: они включали асинхронные ADO. NET конечные точки, но реализовали их синхронно . К сожалению, это то, что вы «просто должны знать», поскольку AFAIK нигде не задокументировано, за исключением нескольких вопросов о переполнении стека.

Поскольку вы работаете над приложением GUI, использование Task.Run будет быть приемлемым обходным путем:

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

Кроме того, вы можете удалить MySql.Data и заменить его на MySqlConnector, который использует истинные асинхронные реализации.

...