Блокируется UI при работе с другим окном

123
01 сентября 2019, 12:30

Переделал код под async await, и всё работает замечательно, до тех пор, пока не начинаю работать с другим окном. В этом случае UI главного окна блокируется.

Записал видео-вопросом - https://www.youtube.com/watch?v=t2T_rnYsYWs

Собственно, вопрос из видео: как выполнять работу в разных UI независимо?

P.S. пробовал через код-помощник

static class AsyncHelper {
    static public ThreadPoolRedirector RedirectToThreadPool() =>
        new ThreadPoolRedirector();
}
public struct ThreadPoolRedirector : INotifyCompletion {
    // awaiter и awaitable в одном флаконе
    public ThreadPoolRedirector GetAwaiter() => this;
    // true означает выполнять продолжение немедленно 
    public bool IsCompleted => Thread.CurrentThread.IsThreadPoolThread;
    public void OnCompleted(Action continuation) =>
        ThreadPool.QueueUserWorkItem(o => continuation());
    public void GetResult() { }
}

пробовал через

await Task.Run(()=>{
...
});

но результат тот же.

Код из видео:

1.

var updateThread = new Thread(async () => await UpdateAsync());
updateThread.Start();

2.

public async Task UpdateAsync() {
        //await AsyncHelper.RedirectToThreadPool();
        while (true) {
            string response = await ircClient.fetchServerMessage();
            if (response != null) {
                if (response.Contains("PRIVMSG")) {
                    ChatMessageArgs chatMessage = await stripChatMessageAsync(response);
                    if (ignoreList.FindIndex(x => x.Equals(chatMessage.name, StringComparison.OrdinalIgnoreCase)) != -1) continue;
                    OnChatReceived?.Invoke(this, chatMessage);
                } 
            }
        }
    }

3.

private async void ChatMessageReceived(Bot bot, ChatMessageArgs chatMessage) {          
    noticePanel.Dispatcher.Invoke(() => { noticePanel.chatNoticeNew(chatMessage); });
}

4.

public void chatNoticeNew(ChatMessageArgs chatMessage) {
        while (noticeList.Count < 10) {
            ChatNoticeWFR newNotice = new ChatNoticeWFR();
            noticeList.Add(newNotice);
        }
        ChatNoticeWFR notice = noticeList[0];
        noticeList.RemoveAt(0);
        noticeList.Insert(noticeList.Count, notice);
        _stackPanel.Children.Remove(notice);
        _stackPanel.Children.Insert(0, notice);
    }
Answer 1

Для коллекций используйте ItemsControl, в которой есть свой темплейт и биндите значения из модели на вьюху.

В дополнение, для разделения вьюх и их логики используют архитектурный паттерн MVVM.

Почитать:

  • https://www.wpf-tutorial.com/list-controls/itemscontrol/
  • https://metanit.com/sharp/wpf/22.1.php

Дополение:

Update у вас помечен модификатором async, соответственно, возвращайте Task.

Использование таски не гарантирует создание нового потока. Создавайте новый поток:

var updateThread = new Thread(async () => await UpdateAsync());
updateThread.Start();

Не забудьте сделать объект диспоузаблом и на диспоузе стопать этот поток: updateThread.Abort();

P.S. что делает у вас stripChatMessageAsync()? Помните, что вычисляемые операции оборачивать в таску не следует - это бесполезно.

READ ALSO
Передать объект из JS в PHP?

Передать объект из JS в PHP?

Как передать объект почему не получается? Что я не так делаю? JS:

124
Подключиться к Access на php

Подключиться к Access на php

Имеется сайт на PHP+MySql, unix-хостингЕсть необходимость подключения к файлам БД Access предварительно загруженных по ФТП в папку сайта

133
vk бот на php с циклической функцией

vk бот на php с циклической функцией

Возможно ли на php используя Callback API vk написать бота, который по команде начинает выполнять циклическую функцию (допустим парсинг сайта каждую...

102
Class not found (0)

Class not found (0)

[Error] Class 'Has\Module\CompanyPoints' not found (0)

122