3

私はアプリに取り組んでおり、すべての優れたベストプラクティスを実行しようとしています。これが私がやりたいことをしないコードです:

async public Task DoStuff()
{
    DispatcherAdapter.Current.BeginInvoke(() => { myObject.SomeProperty = "new value"; });
    await DatabaseAdapter.Current.SaveItem(TableName, myObject);
}

上記のコードは、更新されたプロパティ値でアイテムをデータベースに保存しません。これは、待機している非同期メソッドが機能する前に BeginInvoke() が必ずしも終了しないためだと思います。DispatcherAdapter は、次のようにバックグラウンドで Deployment.Current.Dispatcher を使用するだけです。

    public override void BeginInvoke(Action a)
    {
        Deployment.Current.Dispatcher.BeginInvoke(a);
    }

ここに私が調べたものがありますが、うまくいきません:

  • BeginInvoke() 呼び出しの待機中 - Task が返されないため機能せず、Dispatcher.BeginInvoke が実際にいつ終了したかがわからない状態にドリルダウンします
  • BeginInvoke() から返された DispatcherOperation オブジェクトを操作しようとしています- 通常の .NET で利用できる Completed イベントは Windows Phone 8 では利用できません
  • SynchronizationContext.Send() の使用- DispatcherSynchronizationContext.Current は常に null であるため、機能しません...以下の無関係なコードを参照してください。

    public async override Task Invoke(Action a)
    {
        await Task.Factory.StartNew(() => { DispatcherSynchronizationContext.Current.Send(new SendOrPostCallback(delegate { a.Invoke(); }), null); });
    }
    

基本的に、無効なクロススレッド アクセスを回避し、Windows Phone 8 の非同期メソッド内でコードが特定の順序で実行されるようにするにはどうすればよいですか? 私は .SaveItem を移動して BeginInvoke 内に移動できると思います...しかし、それは抜け道のように感じます.BeginInvoke呼び出しを待つことはできません(非同期メソッドに入れるのはかなり無意味です)。私が何をすべきかを知ることができてうれしい/この状況で他の人がやったこと.

4

2 に答える 2

2

asyncこれを行う最も簡単な方法は、UIスレッドからメソッドを呼び出すことです。次に、これを行うことができます:

public async Task DoStuffAsync()
{
  myObject.SomeProperty = "new value";
  await DatabaseAdapter.Current.SaveItem(TableName, myObject);
}

asyncメソッドがバックグラウンドスレッドで何らかの操作を行う必要がある場合は、それをでラップしますTask.Run

于 2012-12-05T13:07:52.913 に答える
1

最終的に独自のDispatcherSynchronizationContextを作成しましたが、すべてが機能しているように見えました。

    public async override Task Invoke(Action a)
    {
        DispatcherSynchronizationContext dsc = new DispatcherSynchronizationContext(Deployment.Current.Dispatcher);
        await Task.Factory.StartNew(() => { dsc.Send(new SendOrPostCallback(delegate { a.Invoke(); }), null); });
    }

これが推奨される方法であるかどうか、またはこの方法でDispatcherSynchronizationContextを使用する際の落とし穴があるかどうかはまだわかりません...しかし、UIスレッドに影響を与えるこのヘルパーメソッドを待つことができるので、それが始まりです。 。

于 2012-12-05T09:27:22.087 に答える