繁体   English   中英

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

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

我有一个Singleton类LocationManager,它处理Windows Metro应用程序中的所有地理位置。

由于Geolocator对象中的.PositionChanged事件通常在后台线程上引发,因此我想到了将类的引用传递给CoreDispatcher,以便它可以在UI线程上自动引发自己的事件。 例如:

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));
            }
        );   
    }

我想知道是否应该在我的每个监听UI对象中(例如MainPage.xaml.cs)放置dispatcher.RunAsync东西-但是这种方法似乎可以节省重复的代码。 这种方法有什么缺点吗? 例如,对调度程序的引用是否过时或无效?

您是否考虑过观察者模式

您所描述的听起来像是发布者-订阅者关系。 当发布者有要发布的内容时,所有订阅者都会收到该发布。 您的发布者不必单身,但可以是。 有帮助吗?

就个人而言,我避免将Dispatcher (或类似的)对象放在UI层上方的任何层中。 SynchronizationContext更好。

在您的情况下,我将使用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