В моем приложении WPF я асинхронно общаюсь с сервером. Следовательно, обратный вызов не будет запускаться в потоке пользовательского интерфейса, и, поскольку мне нужно сделать там некоторые вещи WPF (создать объект InkPresenter), мне нужно, чтобы он запускался в потоке пользовательского интерфейса. Ну, на самом деле требование состоит в том, чтобы он запускался в потоке с режимом квартиры STA. Я попытался создать новый поток в режиме STA, но в результате поток пользовательского интерфейса не смог получить доступ к InkPresenter, поскольку он «принадлежал другому потоку».
Что я хочу сделать в обратном вызове, так это использовать Диспетчер для вызова моей функции, для которой требуется STA. Это похоже на правильный подход? Я делаю это сейчас, но все равно не получается. В моей функции обратного вызова я запускаю следующую функцию, которая теперь пытается обеспечить выполнение адресуемой функции в потоке пользовательского интерфейса.
private void UpdateAnnotationsForCurrentFrameCollection()
{
if (Dispatcher.CurrentDispatcher.CheckAccess())
{
DoSomethingIncludingInkPresenter();
}
else
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
new Action(DoSomethingIncludingInkPresenter));
}
}
private void DoSomethingIncludingInkPresenter()
{
var inkPresenter = XamlReader.Parse(_someXamlString) as InkPresenter;
// Do something with the inkPresenter..
}
Как видно из примера, я использую CheckAccess (), чтобы гарантировать, что я вызываю функцию только в том случае, если она еще не запущена в потоке пользовательского интерфейса. Когда мой обратный вызов вызывает эту функцию, CheckAccess () всегда истинно, но Dispatcher.CurrentDispatcher.Thread.ApartmentState
- это MTA. Почему? Я попытался удалить CheckAccess () и всегда выполнял Invoke, но ApartmentState остается MTA, и создание InkPresenter не удается.
Может ли кто-нибудь объяснить мне, что я здесь делаю не так? У меня не тот Диспетчер или что-то в этом роде? Это правильный подход к обеспечению того, чтобы что-то запускалось в потоке пользовательского интерфейса?