Я использую визуальный контроль в своем проекте, который из библиотеки, для которой у меня нет источника.
Требуется слишком много времени для обновления (примерно 200 мс) для хорошей реакции на пользовательский интерфейс с тремя из этих элементов управления на экране одновременно. (Мне может потребоваться обновить все три сразу, что оставляет мой пользовательский интерфейс застрял на ~ 600 мс, пока они все думают).
Я прочитал несколько сообщений о TaskSchedulers и начал изучать функции задач Parallel как способ запуска каждого из этих элементов управления в своем потоке. Платформа будет многоядерной, поэтому я хочу воспользоваться одновременной обработкой.
Проблема в том, что я даже не знаю, чего я не знаю о том, как это сделать, хотя..
Есть ли подходящий шаблон проектирования для запуска элемента управления в отдельном потоке из основного потока пользовательского интерфейса в WPF?
Конкретно: это элемент управления сторонней картой, когда при новом местоположении или уровне масштабирования требуется слишком много времени для перерисовки (~ 200 мс). Возможно, три из этих обновлений не превышают 4 Гц - очевидно, что они не ускорятся.
Я инкапсулировал элемент управления WPF в usercontrol и должен запускать каждый экземпляр в его собственном потоке, сохраняя при этом пользовательский ввод (например, щелчки мыши).
UPDATE: пока я чувствую себя в стороне от решения, я реализовал следующее. Мой основной (UI) поток генерирует поток, который создает новое окно, содержащее соответствующий элемент управления, и находит его в правильной позиции (так что это похоже на обычный контроль).
_leftTopThread = new Thread(() =>
{
_topLeftMap = new MapWindow()
{
WindowStartupLocation = WindowStartupLocation.Manual,
Width = leftLocation.Width,
Height = leftLocation.Height,
Left = leftLocation.X,
Top = leftLocation.Y,
CommandQueue = _leftMapCommandQueue,
};
_topLeftMap.Show();
System.Windows.Threading.Dispatcher.Run();
});
_leftTopThread.SetApartmentState(ApartmentState.STA);
_leftTopThread.IsBackground = true;
_leftTopThread.Name = "LeftTop";
_leftTopThread.Start();
Где CommandQueue
является Thread-safe BlockingCollection Очередь для отправки команд на карту (перемещение местоположения и т.д.).
Проблема в том, что я могу либо
- имеет пользовательский ввод из-за вызова
System.Windows.Threading.Dispatcher.Run()
- или заблокировать CommandQueue, прослушивая команды, отправленные основным потоком
Я не могу отжимать ожидающие команды, потому что он впитал бы весь мой процессор потоков!
Можно ли заблокировать и запустить сообщение-насос события?