簡體   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