IMO answers that say you have to start a thread to handle this are wrong. You need to flip the window back to the main dispatcher thread.
In WPF
public ShellViewModel( [NotNull] IWindowManager windows, [NotNull] IWindsorContainer container) { if (windows == null) throw new ArgumentNullException("windows"); if (container == null) throw new ArgumentNullException("container"); _windows = windows; _container = container; UIDispatcher = Dispatcher.CurrentDispatcher;
and then when some event occurs in another thread (thread pool thread in this case):
public void Consume(ImageFound message) { var model = _container.Resolve<ChoiceViewModel>(); model.ForImage(message); UIDispatcher.BeginInvoke(new Action(() => _windows.ShowWindow(model))); }
WinForms equivalent
Do not install UIDispatcher on anything, then you can do:
public void Consume(ImageFound message) { var model = _container.Resolve<ChoiceViewModel>(); model.ForImage(message); this.Invoke( () => _windows.ShowWindow(model) ); }
DRYing for WPF:
Man, so much code ...
public interface ThreadedViewModel : IConsumer {
and in the view model:
public void Consume(ImageFound message) { var model = _container.Resolve<ChoiceViewModel>(); model.ForImage(message); this.BeginInvoke(() => _windows.ShowWindow(model)); }
Hope this helps.
Henrik
source share