0

wp8で複雑なタスクをキューに入れる正しい方法は何ですか?

タスクは次のとおりです。

  1. ProgressIndicatorモデル変数を更新して表示する
  2. wcf サービスへのデータのフェッチまたは保存 ( UploadStringAsync)
  3. からの結果を使用して、潜在的にデータ バインドされたモデルを更新していUploadStringCompletedます。
  4. ProgressIndicatorモデル変数を更新して非表示にする

現在、コマンド オブジェクトのキューを所有するクラスで作業しており、まだ実行されていない場合に項目が追加されたときに開始される単一のスレッドを実行しています。

ただし、コードの実行が停止するタスクまたはサブタスクの待機に問題があります。

以前は async await を使用していましたが、いくつかのレベルを下げると、動作がますます予測不能になりました。

私が欲しいのは、コマンド オブジェクトを作成してキューに入れることができるメイン スレッドです。コマンド オブジェクトは一度に 1 つずつ実行し、前のオブジェクトが完全に終了するまで新しいオブジェクトを開始しないようにする必要があります。コマンド オブジェクトは、必要に応じてディスパッチャを使用してメイン スレッドにアクセスできる必要があります。

4

1 に答える 1

6

async/を使用する場合await、別のスレッドは必要ありません (CPU バウンド処理がないため)。

あなたの場合、非同期デリゲートのキューが必要なだけのようです。非同期デリゲートの本来の型は、Func<Task>(戻り値なし) またはFunc<Task<T>>(戻り値あり) です。この小さなヒントは、残念ながら現時点ではあまり知られていません。

したがって、非同期デリゲートのキューを宣言します。

private readonly Queue<Func<Task>> queue = new Queue<Func<Task>>();

次に、キューを (非同期で) 処理するだけの単一の「トップレベル」タスクを作成できます。

private Task queueProcessor;

これ以上アイテムがない場合はいつでもqueueProcessor可能です。nullでない場合は常に、次のnullメソッドを表します。

private async Task ProcessQueue()
{
  try
  {
    while (queue.Count != 0)
    {
      Func<Task> command = queue.Dequeue();
      try
      {
        await command();
      }
      catch (Exception ex)
      {
        // Exceptions from your queued tasks will end up here.
        throw;
      }
    }
  }
  finally
  {
    queueProcessor = null;
  }
}

メソッドEnqueueは次のようになります。

private void Enqueue(Func<Task> command)
{
  queue.Enqueue(command);
  if (queueProcessor == null)
    queueProcessor = ProcessQueue();
}

現在、例外処理を次のように設定しています。キューに入れられたコマンドが例外をスローすると、キュー プロセッサは処理を停止します (同じ例外が発生します)。これは、アプリケーションにとって最適な動作ではない可能性があります。

次のように使用できます (もちろん、ラムダまたは実際のメソッドのいずれかを使用)。

Enqueue(async () =>
{
  ShowProgressIndicator = true;
  ModelData = await myProxy.DownloadStringTaskAsync();
  ShowProgressIndicator = false;
});

の使用に注意してくださいDownloadStringTaskAsyncEAP メンバー用に TAP ラッパーを作成すると、asyncコードがより「自然に見える」(つまり、より単純になる) ようになります。

これは非常に複雑なので、別のクラスに入れることをお勧めしますが、最初にエラーを処理 (および表面化) する方法を決定する必要があります。

于 2013-05-20T12:54:06.833 に答える