简体   繁体   English

是否可以将CoreDispatcher传递给Singleton以在UI线程上自动引发事件?

[英]Is it OK to pass CoreDispatcher to a Singleton to auto-raise events on UI thread?

I have a Singleton class, LocationManager that handles all the Geo-Location in my Windows Metro app. 我有一个Singleton类LocationManager,它处理Windows Metro应用程序中的所有地理位置。

Because .PositionChanged events from the Geolocator object are often raised on a background thread, I thought of passing my class a reference to a CoreDispatcher so that it can automatically raise its own events on the UI Thread. 由于Geolocator对象中的.PositionChanged事件通常在后台线程上引发,因此我想到了将类的引用传递给CoreDispatcher,以便它可以在UI线程上自动引发自己的事件。 eg: 例如:

public class LocationManager
{
    // Events
    public event EventHandler<LocationUpdatedEventArgs> LocationUpdated = delegate { };

    // Private members
    Geolocator gl = null;
    CoreDispatcher dispatcher = null;

    public void StartUpdating(CoreDispatcher dispatcher)
    {
        this.dispatcher = dispatcher;

        gl = new Geolocator();
        gl.PositionChanged += gl_PositionChanged;
    }

    async void gl_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
    {
        // Ensure this class's event is raised on UI thread
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal,  () => 
            {
                LocationUpdated(this,  new LocationUpdatedEventArgs(args.Position));
            }
        );   
    }

I wonder if I should be putting the dispatcher.RunAsync stuff in each of my listening UI objects instead (ie MainPage.xaml.cs) - but this approach seems to save duplication of code. 我想知道是否应该在我的每个监听UI对象中(例如MainPage.xaml.cs)放置dispatcher.RunAsync东西-但是这种方法似乎可以节省重复的代码。 Are there any drawbacks to this approach? 这种方法有什么缺点吗? For example, could the reference to the dispatcher ever become stale or invalid? 例如,对调度程序的引用是否过时或无效?

Have you considered the Observer Pattern ? 您是否考虑过观察者模式

What you are describing sounds like a publisher-subsriber relationship. 您所描述的听起来像是发布者-订阅者关系。 When the publisher has something to publish, all subsribers receive that publication. 当发布者有要发布的内容时,所有订阅者都会收到该发布。 Your publisher does not have to be singleton, but it can be. 您的发布者不必单身,但可以是。 Does that help? 有帮助吗?

Personally, I avoid placing Dispatcher (or similar) objects in any layer above the UI layer. 就个人而言,我避免将Dispatcher (或类似的)对象放在UI层上方的任何层中。 SynchronizationContext is better. SynchronizationContext更好。

In your case, I would take an approach using Dataflow (something very similar can be done using Rx ): 在您的情况下,我将使用Dataflow的方法(可以使用Rx完成非常相似的操作):

public class LocationManager
{
  // Events
  public event EventHandler<LocationUpdatedEventArgs> LocationUpdated = delegate { };

  // Private members
  Geolocator gl = null;
  ActionBlock<PositionChangedEventArgs> block = null;

  public void StartUpdating()
  {
    // Set up the block to raise our event on the UI thread.
    block = new ActionBlock<PositionChangedEventArgs>(
        args =>
        {
          LocationUpdated(this, new LocationUpdatedEventArgs(args.Position));
        },
        new ExecutionDataflowBlockOptions
        {
          TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(),
        });

    // Start the Geolocator, sending updates to the block.
    gl = new Geolocator();
    gl.PositionChanged += (sender, args) =>
    {
      block.Post(args);
    };
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM