1

状態を渡したい次の拡張メソッドがあります。

     // Overload 2
    public static Task<TableQuerySegment<T>> ExecuteQuerySegmentedAsync<T> (this CloudTable tbl, TableQuery<T> query, TableContinuationToken continuationToken, CancellationToken token) where T : ITableEntity, new()
    {
        return tbl.ExecuteQuerySegmentedAsync<T>(query, continuationToken, null, null, token);
    }

    // Overload 5
    public static Task<TableQuerySegment<TElement>> ExecuteQuerySegmentedAsync<TElement>(this CloudTable tbl, TableQuery<TElement> query, TableContinuationToken continuationToken, TableRequestOptions opt, OperationContext ctx, CancellationToken token) where TElement : ITableEntity, new()
    {
        ICancellableAsyncResult result = null;

        if (opt == null && ctx == null)
            result = tbl.BeginExecuteQuerySegmented<TElement>(query, continuationToken, null, tbl);
        else
            result = tbl.BeginExecuteQuerySegmented<TElement>(query, continuationToken, opt, ctx, null, tbl);

        var cancellationRegistration = token.Register(result.Cancel);

        return Task.Factory.FromAsync(result, iAsyncResult =>
        {
            CloudTable currentTable = iAsyncResult.AsyncState as CloudTable;

            cancellationRegistration.Dispose(); // todo: handle cleanup of this (deregistration)
            return currentTable.EndExecuteQuerySegmented<TElement>(result);
        });
    }

    // Overload 3
    public static Task<TableQuerySegment<R>> ExecuteQuerySegmentedAsync<T, R>(this CloudTable tbl, TableQuery<T> query, EntityResolver<R> resolver, TableContinuationToken continuationToken, CancellationToken token) where T : ITableEntity, new()
    {
        return tbl.ExecuteQuerySegmentedAsync<T, R>(query, resolver, continuationToken, null, null, token);
    }

    // Overload 6
    public static Task<TableQuerySegment<R>> ExecuteQuerySegmentedAsync<TElement, R>(this CloudTable tbl, TableQuery<TElement> query, EntityResolver<R> resolver, TableContinuationToken continuationToken, TableRequestOptions opt, OperationContext ctx, CancellationToken token) where TElement : ITableEntity, new()
    {
        ICancellableAsyncResult result = null;

        if (opt == null && ctx == null)
            result = tbl.BeginExecuteQuerySegmented<TElement, R>(query, resolver, continuationToken, null, null);
        else
            result = tbl.BeginExecuteQuerySegmented<TElement, R>(query, resolver, continuationToken, opt, ctx, null, null);

        var cancellationRegistration = token.Register(result.Cancel);

        return Task.Factory.FromAsync(result, iAsyncResult =>
        {
            CloudTable currentTable = iAsyncResult.AsyncState as CloudTable;

            cancellationRegistration.Dispose(); // todo: handle cleanup of this (deregistration)
            return currentTable.EndExecuteQuerySegmented<R>(result);
        });
    }

このようにコードを呼び出すことができます

            // prepare the query
            trustsInBatchesOf100 = tableSymmetricKeys.ExecuteQuerySegmentedAsync(query, token, opt, ctx, cancelToken);

            // my state
            object mystate  = trustsInBatchesOf100.AsyncState;

を含めるように拡張メソッドを変更する方法を見つけようとして立ち往生していますstateObject問題は、 TaskFactory.FromAsyncで正しいオーバーロードを見つけて、拡張メソッドで正しく実装することです。

質問

上記の拡張メソッドを変更して、状態パラメーターを正しく受け入れるにはどうすればよいですか?

その他のソース コード

    private CloudTableClient tableClient;
    private CloudStorageAccount account;
    private TableRequestOptions opt;

    List<Task<TableResult>> AllRunningTasks = null;

    public async Task GetTrustsAndValues(string thingToSearchFor,string trustStartingPoint, 
        int depth,
        TableQuery query,                             
         OperationContext ctx, CancellationToken cancelToken)
    {
        TrustState asyncState = new TrustState() { ThingToSearchFor = thingToSearchFor, TimeStarted = DateTime.UtcNow };

        var ret = new TrustTree<string>(thingToSearchFor, "start", 10);


        CloudTableClient client = account.CreateCloudTableClient();
        CloudTable tableSymmetricKeys = client.GetTableReference("SymmetricKeys5"); 

       // List<Task> taskList = new List<Task>();

        TableContinuationToken token = new TableContinuationToken() { };
        Task<TableQuerySegment<DynamicTableEntity>> trustsInBatchesOf100 = null;

        while (true)
        {
            // prepare the query
            trustsInBatchesOf100 = tableSymmetricKeys.ExecuteQuerySegmentedAsync(query, token, opt, ctx, cancelToken);

            object mystate  = trustsInBatchesOf100.AsyncState;

            // Run the method
            trustsInBatchesOf100.Wait();

            // Create tasks for each of the 100 domains found.
            IEnumerable<Task<TableResult>> getTrustDataQuery =
                          from domainData in trustsInBatchesOf100.Result select QueryPartnerForData(ref ret,domainData, thingToSearchFor, client, cancelToken);

            // Save the count of lookups as appropriate  
            asyncState.RunningDirectQueries = getTrustDataQuery.Count();

            // Run up to 100 lookups on those domains.
            var runningTasks = getTrustDataQuery.ToList();

            // Add running tasks to the full compilation of running tasks
            AllRunningTasks.AddRange(runningTasks );

            // Prepare for next iteration or quit
            if (token == null)
            {
                break;
            }
            else
            {
                token = trustsInBatchesOf100.Result.ContinuationToken;

                // todo: persist token  token.WriteXml()
            }
        }
    }



    private static Task<TableResult> QueryPartnerForData(ref  TrustTree<string> tree, DynamicTableEntity domainData, string thingToSearchFor, CloudTableClient client, CancellationToken cancelToken)
    {
        // Create the table client.
        CloudTable tableDirectQuery = client.GetTableReference(String.Format("{0}_FW", domainData.RowKey));

        // Retrieve the entity with partition key of "Smith" and row key of "Jeff"
        TableOperation tableOperation = TableOperation.Retrieve(domainData.RowKey, thingToSearchFor);

        // Retrieve entity asynchronously
        return tableDirectQuery.ExecuteAsync(tableOperation, cancelToken);
    }

    public async void SaveCompletedQueriesTo()
    {
        while (AllRunningTasks.Count > 0)
        {
            // Identify the first task that completes.
            Task<TableResult> firstFinishedTask = await Task.WhenAny(AllRunningTasks);

            // ***Remove the selected task from the list so that you don't
            // process it more than once.
            AllRunningTasks.Remove(firstFinishedTask);

            // Await the completed task.
            var taskOfTableResult = await firstFinishedTask;

            //todo: asyncState: need to know what the 
            // - target to save to is.
        }

        // TODO: if all tasks have completed then update 
    }
4

1 に答える 1

-1

Microsoft.WindowsAzure.StorageClient.Asyncプロジェクトを見たことがありますか?(NuGetでも利用可能)。それはいくつかのアイデアを提供するか、すでにあなたの問題を解決しているかもしれません。それ以外の場合は、変更が適切に行われたときに、そのプロジェクトに変更を加えることを検討してください。

于 2012-12-31T17:35:34.947 に答える