Проблема с несколькими диспетчерами - PullRequest
1 голос
/ 08 декабря 2008

У меня следующая проблема: многопоточное приложение WPF, реализация Model View Presenter. Представители и представления, которые принадлежат друг другу, создаются фабрикой в ​​отдельном потоке и должны получать отдельный диспетчер.

Public Function CreatePresenter(Of T As {New, Class})(ByVal p_eCreationOptions As eViewCreationOptions) As T Implements IPresenterFactory.CreatePresenter

    Select Case p_eCreationOptions
        Case eViewCreationOptions.CreateInCallingThread
            CreatePresenter(Of T)()
        Case eViewCreationOptions.CreateInNewThread
            Dim oThread As New Thread(New ThreadStart(AddressOf CreatePresenter(Of T)))
            oThread.SetApartmentState(System.Threading.ApartmentState.STA)
            oThread.Start()
            oThread.Join()
        Case Else
            Throw New InvalidOperationException("Need to specify creation options.")
    End Select

    Return CType(m_oCreatedPresenter, T)

End Function

Private Sub CreatePresenter(Of T As {New, Class})()
    m_oCreatedPresenter = Activator.CreateInstance(Of T)()
End Sub

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

Public Overloads Sub Show()
    Console.WriteLine ("Show Caller ThreadID = " & Thread.CurrentThread.ManagedThreadId)
    MyBase.Show()
    System.Windows.Threading.Dispatcher.Run()
End Sub

Но то, что я хочу сделать, - это когда метод в презентаторе вызывается из другого потока, отличного от того, где живет докладчик, снова вызывать метод в потоке презентатора, где у него есть собственный Диспетчер, так что я не Мне не нужно иметь дело с Диспетчером по вызовам между моим Докладчиком и представлением. Это вообще возможно, мой дизайн несовершенен или есть лучший способ добиться того, чего я хочу?

1 Ответ

2 голосов
/ 14 февраля 2009

Проблема в том, что Dispatcher не запускается, когда в новом потоке не создается экземпляр DispatcherObject, но если вы создаете экземпляр фиктивного объекта и затем вызываете метод вашего докладчика, диспетчер будет работать правильно. Например

 private void ThreadStartingPoint()  
 {  
     var dummyDispatcherObject = new Style();  
     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(CreatePresenterInternal));  
     Dispatcher.Run();  
}  

Полное решение этой проблемы можно найти в моем блоге .

...