1

このコードがどのように実行され、「結果」がどこにあるのか、どの時点で完全な結果を得ることができるのかを理解するのを手伝ってもらえますか?

protected void QuerySongsExecuteSegmentedAsync(CloudTableClient cloudTableClient)
{
  TableServiceContext tableServiceContext = cloudTableClient.GetDataServiceContext();
  tableServiceContext.ResolveType = (unused) => typeof(Song); 

  CloudTableQuery<Song> cloudTableQuery =
    (from entity in tableServiceContext.CreateQuery<Song>("Songs").Take(10)
    select entity ).AsTableServiceQuery<Song>();
  IAsyncResult iAsyncResult =
    cloudTableQuery.BeginExecuteSegmented(BeginExecuteSegmentedIsDone, cloudTableQuery);
} 

static void BeginExecuteSegmentedIsDone(IAsyncResult result)
{
  CloudTableQuery<Song> cloudTableQuery = result.AsyncState as CloudTableQuery<Song>;
  ResultSegment<Song> resultSegment = cloudTableQuery.EndExecuteSegmented(result); 

  List<Song> listSongs = resultSegment.Results.ToList<Song>(); 

  if (resultSegment.HasMoreResults)
  {
    IAsyncResult iAsyncResult =
      cloudTableQuery.BeginExecuteSegmented(
       resultSegment.ContinuationToken, BeginExecuteSegmentedIsDone, cloudTableQuery);
  }
}
4

2 に答える 2

2

Windows Azure テーブル ストレージに対するクエリは、継続トークンを使用して部分的な結果を返すことがあります。つまり、結果の次のバッチを取得するには、(継続トークンを使用して) クエリを再発行する必要があります。通常、単に使用してから列挙するコードが表示.AsTableServiceQuery()されます。これにより、列挙中に呼び出しのチェーンが透過的に発生します。

このコードは、BeginExecuteSegmented を使用して結果の各バッチを取得することにより、明示的に実行しています。行のすぐ下で、それらの sList<Song> listSongs = resultSegment.Results.ToList<Song>()を消費できるはずです。Song(さらに追加される可能性がありますが、それらの結果は有効で使用できるはずです。)

于 2011-01-21T07:21:01.403 に答える
2

TPL (Task Parallel Library) を使用して非同期に実行する場合は、次のようなパターンを使用できます。

    public static Task<IEnumerable<T>> ExecuteAsync<T>(DataServiceQuery<T> query, TableServiceContext tableContext)
    {
        List<T> values = null;

        var cloudQuery = query.AsTableServiceQuery();

        Func<ResultSegment<T>, Task<ResultSegment<T>>> getSegment = null;

        getSegment = new Func<ResultSegment<T>, Task<ResultSegment<T>>>((previous) =>
        {
            return ExecuteSegmentAsync(cloudQuery, previous).ContinueWith(exec =>
            {                    
                if (exec.IsFaulted || exec.IsCanceled)
                {
                    return exec;
                }
                else
                {
                    var segment = exec.Result;
                    if(segment.HasMoreResults)
                    {
                        if(values == null)
                        {
                            values = new List<T>();
                        }
                        values.AddRange(segment.Results);
                        return getSegment(segment);                        
                    }
                    else
                    {
                        return exec;
                    }
                }
            }).Unwrap();
        });

        return getSegment(null).ContinueWith(exec =>
        {
            exec.ThrowOnError("ExecuteAsync");
            var segment = exec.Result;

            if(values == null)
            {
                return segment.Results;
            }
            else
            {
                values.AddRange(segment.Results);
                return values;
            }
        });       
    }

    private static Task<ResultSegment<T>> ExecuteSegmentAsync<T>(CloudTableQuery<T> query, ResultSegment<T> previous)
    {
        var tcs = new TaskCompletionSource<ResultSegment<T>>();

        RetryPolicy.ExecuteAction(ac =>
        {
            // Invoke the begin method of the asynchronous call.
            if(previous != null)
            {
                query.BeginExecuteSegmented(previous.ContinuationToken, ac, null);                
            }
            else
            {
                query.BeginExecuteSegmented(ac, null);                
            }
        },
        ar =>
        {
            // Invoke the end method of the asynchronous call.
            return query.EndExecuteSegmented(ar);
        },
        values =>
        {
            tcs.SetResult(values);                
        },
        ex =>
        {
            // Async opetation failed after multiple retries
            tcs.SetException(ex);
        });

        return tcs.Task;
    }
于 2012-08-29T18:34:05.450 に答える