18

Windows Azure の開発は初めてで、Windows Azure ストレージ テーブルにデータを格納する必要があります。

このテーブルは、実際には、Azure ストレージ ドライブにある一部のファイルをすばやく検索するメカニズムを提供するためにのみ存在します。

したがって、アプリケーションの起動時にこのテーブルにデータを入力することを計画していました (つまり、Web アプリケーションのグローバル アプリケーションの起動時)。

変更のためにこのテーブルを維持しようとするのではなく、アプリケーションが実行されていない間にドライブに発生する可能性のある変更。または、このドライブは単なるリソースの vhd であるため、場合によっては新しい vhd をアップロードすることもできます。

これを維持しようとする手間ではなく。アプリケーションが起動するたびにこのテーブルを再構築するだけで十分です。

テーブルが既に存在するかどうかを確認し、存在する場合は削除してから、新しいテーブルを再作成するコードをまとめ始めました。

var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString);
var tableClient = storageAccount.CreateCloudTableClient();
var rmsTable = tableClient.GetTableReference("ResourceManagerStorage");
rmsTable.DeleteIfExists();
rmsTable.Create();

これはうまくいかないだろうと思っていました。そして、次のエラーが表示されます。

The remote server returned an error: (409) Conflict. 

HTTP/1.1 409 Conflict
Cache-Control: no-cache
Transfer-Encoding: chunked
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: c6baf92e-de47-4a6d-82b3-4faec637a98c
x-ms-version: 2012-02-12
Date: Tue, 19 Mar 2013 17:26:25 GMT

166
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>TableBeingDeleted</code>
  <message xml:lang="en-US">The specified table is being deleted. Try operation later.
RequestId:c6baf92e-de47-4a6d-82b3-4faec637a98c
Time:2013-03-19T17:26:26.2612698Z</message>
</error>
0

これを行う正しい方法は何ですか?テーブルがいつ削除されたかを知らせるためにサブスクライブできるイベントはありますか? これを実装するための最良の方法に関する他の提案はありますか?

4

2 に答える 2

29

MSDNから:「テーブルの削除が完了するまでに少なくとも40秒かかる可能性があることに注意してください。テーブルの削除中にテーブルに対して操作を試行すると、サービスはステータスコード409(競合)を返し、追加のエラー情報は次のことを示します。テーブルが削除されています。」

これに対処する唯一の方法は、別の名前のテーブルを作成することです。これは、名前にタイムスタンプまたはGUIDを追加するのと同じくらい簡単です。ごみの片付けには注意してください。

于 2013-03-19T19:39:41.343 に答える
15

同じテーブル名を使用する必要がある場合は、拡張メソッドを使用できます。

public static class StorageExtensions
{
    #region Non-async

    public static bool SafeCreateIfNotExists(this CloudTable table, TimeSpan? timeout, TableRequestOptions requestOptions = null, OperationContext operationContext = null)
    {
        Stopwatch sw = Stopwatch.StartNew();
        if (timeout == null) timeout = TimeSpan.FromSeconds(41); // Assuming 40 seconds max time, and then some.
        do
        {
            if (sw.Elapsed > timeout.Value) throw new TimeoutException("Table was not deleted within the timeout.");

            try
            {
                return table.CreateIfNotExists(requestOptions, operationContext);
            }
            catch (StorageException e) when(IsTableBeingDeleted(e))
            {
                Thread.Sleep(1000);
            }
        } while (true);
    }

    #endregion

    #region Async

    public static async Task<bool> SafeCreateIfNotExistsAsync(this CloudTable table, TimeSpan? timeout, TableRequestOptions requestOptions = null, OperationContext operationContext = null, CancellationToken cancellationToken = default)
    {
        Stopwatch sw = Stopwatch.StartNew();
        if (timeout == null) timeout = TimeSpan.FromSeconds(41); // Assuming 40 seconds max time, and then some.
        do
        {
            if (sw.Elapsed > timeout.Value) throw new TimeoutException("Table was not deleted within the timeout.");

            try
            {
                return await table.CreateIfNotExistsAsync(requestOptions, operationContext, cancellationToken).ConfigureAwait(false);
            }
            catch (StorageException e) when(IsTableBeingDeleted(e))
            {
                // The table is currently being deleted. Try again until it works.
                await Task.Delay(1000);
            }
        } while (true);
    }

    #endregion

    private static bool IsTableBeingDeleted(StorageException e)
    {
        return
            e.RequestInformation.HttpStatusCode == 409
            &&
            e.RequestInformation.ExtendedErrorInformation.ErrorCode.Equals( TableErrorCodeStrings.TableBeingDeleted );
    }
}

警告!スレッドをブロックするため、この方法を使用する場合は注意してください。また、サードパーティ サービス (Azure) がこれらのエラーを生成し続けると、デッド ループに陥る可能性があります。この理由としては、テーブルのロック、サブスクリプションの有効期限切れ、サービスの利用不可などが考えられます。

于 2014-03-05T10:27:31.913 に答える