2015-09-14 38 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); 
      } 
     } 
相关问题