0

Windows Metro アプリですべての地理位置情報を処理する LocationManager というシングルトン クラスがあります。

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 のものを配置する必要があるかどうか疑問に思いますが、このアプローチはコードの重複を節約するようです。このアプローチに欠点はありますか? たとえば、ディスパッチャへの参照が古くなったり無効になったりすることはありませんか?

4

2 に答える 2

0

個人的には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);
    };
  }
}
于 2012-08-30T17:26:09.280 に答える
0

オブザーバー パターンを検討しましたか?

あなたが説明していることは、パブリッシャーとサブスクライバーの関係のように聞こえます。パブリッシャーがパブリッシュするものを持っている場合、すべてのサブスクライバーはそのパブリケーションを受け取ります。パブリッシャーはシングルトンである必要はありませんが、可能です。それは役に立ちますか?

于 2012-08-30T16:29:08.620 に答える