C # WPF - доступ к объектам, созданным в потоке пользовательского интерфейса, из рабочего потока без блокировки - PullRequest
0 голосов
/ 12 ноября 2018

Я работаю над подключаемым WPF-приложением, которое создается из более крупного приложения и регулярно взаимодействует с API основного приложения. У меня проблема в том, что пользовательский интерфейс моего плагина блокируется всякий раз, когда происходит интенсивная работа с основным приложением. В попытке решить эту проблему я выполняю задачу и использую SynchronizationContext пользовательского интерфейса для вызова операции, которая обращается к основному приложению. Для целей тестирования у меня есть простое приложение WPF MainWindow и я задаю ViewContext модели представления следующим образом

((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;

Затем в рамках моей модели представления я выполняю интенсивную операцию из задачи следующим образом.

public void BeginTaskWork()
{
    Task.Factory.StartNew(() =>
    {
        ViewContext.Post(new SendOrPostCallback((o) =>
        {
            PerformIntensiveOperation();
        }), null);
    }
}

Это преодолевает препятствие вызову объектов в потоке пользовательского интерфейса из задачи, но не препятствует зависанию пользовательского интерфейса.

Полагаю, этого следовало ожидать, потому что я все еще выполняю интенсивную задачу в потоке пользовательского интерфейса.

Итак, в основном я спрашиваю, могу ли я что-то сделать, чтобы предотвратить блокировку пользовательского интерфейса при попытке выполнить операции, которые взаимодействуют с родительским приложением.

Обновление:

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

Также, когда я просто пытаюсь выполнить это в другом потоке или задаче, я получаю сообщение об ошибке «System.InvalidOperationException: вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им». По этой причине я попытался комбинировать задачу и контекст синхронизации.

Спасибо.

1 Ответ

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

Выполните вашу интенсивную работу в другом потоке. Это не будет блокировать пользовательский интерфейс. Если вам нужно вызывать объекты в потоке пользовательского интерфейса из другого потока, чем делать именно это - вызывайте их в потоке пользовательского интерфейса. Вы можете сделать это, выполнив Invoke для текущего диспетчера.

await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...