2015-09-14 41 views
3

我有一個消息總線類,它使用Rx在WPF應用程序中推送多個線程事件。 我的問題ObserveOnDispatcher不會在UI線程中調用事件處理程序。ObserveOnDispatcher劑量不會調用UI線程中的處理程序

代碼:

private void button_Click(object sender, RoutedEventArgs e) 
{ 
    var messageBus = new MessageBus(); 
    messageBus.GetMessages<Message>().ObserveOnDispatcher().Subscribe(x => TestHanlder(x)); 

    Trace.WriteLine("Main Thread Id:" + Thread.CurrentThread.ManagedThreadId); 
    var deviceManager = new DeviceManager(messageBus); 
    deviceManager.Start(); 
} 

private void TestHanlder(Message message) 
{ 
    Trace.WriteLine("UI Handler ThreadId:" + Thread.CurrentThread.ManagedThreadId); 
} 

public class DeviceManager 
{ 
    private readonly MessageBus _messageBus; 

    public DeviceManager(MessageBus messageBus) 
    { 
    _messageBus = messageBus; 
    } 

    public void Start() 
    { 
    for (;;) 
    { 
     var t = Task.Factory.StartNew(() => BackGroundTask(), TaskCreationOptions.LongRunning); 
     t.Wait(); 
    } 
    } 

    private void BackGroundTask() 
    { 
    Thread.Sleep(1000); 
    Trace.WriteLine("Push ThreadId:" + Thread.CurrentThread.ManagedThreadId); 
    var message = new Message(); 
    _messageBus.Publish(message); 
    } 
} 

public class MessageBus 
{ 
    readonly ISubject<object> _messages; 

    public MessageBus() 
    { 
    _messages = new Subject<object>(); 
    } 
    public void Publish<TMessage>(TMessage message) 
    { 
    _messages.OnNext(message); 
    } 

    public IObservable<TMessage> GetMessages<TMessage>() 
    { 
    return _messages.OfType<TMessage>(); 
    } 
} 

public class Message 
{ 
    public Message() 
    { 

    } 
} 

Without ObserveOnDispatcher: 
messageBus.GetMessages<Message>().Subscribe(x => TestHanlder(x)); 
..........................Output................................. 
Main Thread Id:8 
Push ThreadId:9 
UI Handler ThreadId:9 
But I need to execute the TestHanlder function in the main thread or UI thread, in my use case above it must be the thread number 8. 

When I use ObserveOnDispatcher: 
messageBus.GetMessages<Message>().ObserveOnDispatcher().Subscribe(x => TestHanlder(x)); 
..........................Output................................. 

Main Thread Id:9 
Push ThreadId:10 
------------------> UI Handler ThreadId: are missing not there!? 
What I'm doing wrong here?!!!!! 
+0

這有什麼錯我的代碼?任何幫助非常感謝... –

+1

有很多「MessageBus」類。如果它在工作線程上產生消息,不是不太可能,那麼ObserveOnDispatcher()將使用錯誤的調度程序。 –

+0

@HansPassant好點我也認爲ObserveOnDispatcher使用錯誤的調度程序,但我怎麼能證明這一點?我應該使用MessageBus類的其他實現嗎? –

回答

3

for (;;) { t.Wait(); }這個代碼在UI線程中執行,並阻止其執行任何其他出動就可以了。 ObserveOnDispatcher工作正常,但您的調度程序線程被阻止。

如果引入異步/的await(將釋放線程),該方案將正常工作:

private async void button_Click(object sender, RoutedEventArgs e) 
    { 
     var messageBus = new MessageBus(); 
     messageBus.GetMessages<Message>().ObserveOnDispatcher().Subscribe(x => TestHanlder(x)); 

     Trace.WriteLine("Main Thread Id:" + Thread.CurrentThread.ManagedThreadId); 
     var deviceManager = new DeviceManager(messageBus); 
     await deviceManager.Start(); 
    } 

    ... 

     public async Task<Unit> Start() 
     { 
      for (;;) 
      { 
       await Task.Factory.StartNew(() => BackGroundTask(), TaskCreationOptions.LongRunning); 
      } 
     } 
相關問題