Как сохранить отзывчивость интерфейса при выполнении фоновых задач - PullRequest
0 голосов
/ 09 ноября 2018

Я реализовал кнопку обновления, которая считывает базу данных и проверяет наличие новых записей и добавляет их в ObservableCollection. У меня есть значок обновления, который вращается в зависимости от значения IsRefreshing. Вот так:

new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            IsRefreshing = true;

            //Reads database
            //ObservableCollection.Add(NewValues)

            IsRefreshing = false;
        }).Start();

Но выполнение этого дает мне исключение:

Этот тип CollectionView не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher.

Я, очевидно, иду по этому пути неправильно, но не уверен, как мне следует, как поддерживать отзывчивость интерфейса при выполнении фоновых задач?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Обычно вы должны добавить этот элемент в коллекцию, но вы должны сделать это в потоке Dispatcher следующим образом:

Application.Current.Dispatcher.Invoke(() => ObservableCollection.Add(NewValues));
0 голосов
/ 09 ноября 2018

Вы не можете изменить пользовательский интерфейс из фонового потока. Все поддерживаемые версии .NET позволяют использовать async/await для выполнения чего-либо в фоновом режиме и возврата в поток пользовательского интерфейса.

ADO.NET, Entity Framework, Dapper и большинство ORM поддерживают асинхронное выполнение. Например, ADO.NET ExecuteReader имеет эквивалентный ExecuteReaderAsync метод. EF ToList() имеет ToListAsync(). Dapper's Query имеет QueryAsync

Вы должны изменить свой обработчик событий на что-то вроде этого:

private async void btn1_Click(object sender, RoutedEventArgs e)
{
    using(var connection = new SqlConnection(_cnString)
    {
        IsRefreshing = true;
        await connection.OpenAsync();
        var results=await connection.QueryAsync<Value>(query);
        //We're now back in the UI thread
        _theCollection.AddRange(results);
        IsRefreshing = false;
    }
}

Когда вызываются OpenAsync или QueryAsync, .NET запускает запрос в фоновом режиме и освобождает текущий поток (UI). По завершении запроса await гарантирует, что выполнение возобновится в исходном потоке, то есть в потоке пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...