?? Contents
Many operations in azure storage take a long time. To improve efficiency, these time-consuming operations respond asynchronously. That is to say, although the function corresponding to these operations is called, the operation may last for a while. If there is no reasonable treatment for the period from the function return to the true end of the operation, our program may have problems. The following describes how to delete a cloudtable.
Problem description
Let's write a simple unit test class to reproduce this problem. First, we define two functions to initialize the test function and clear the data left by the test function. The initializetest function initializes a cloudtable named testtable. If the table does not exist, create it. The cleanuptest function deletes the table.
private const string tableName = "TestTable";private CloudTable table;CloudTableClient tableClient;[TestInitialize]public void InitializeTest(){ string connectionString = Constant.connectionString; CloudStorageAccount storageAccount = Utilities.GetStorageAccount(connectionString); tableClient = storageAccount.CreateCloudTableClient(); this.table = tableClient.GetTableReference(tableName); this.table.CreateIfNotExists();}[TestCleanup]public void CleanupTest(){ if(table != null) { table.DeleteIfExists(); }}
To simplify the issues we will discuss, we add two test cases that will always pass:
[TestMethod]public void TestMethod1(){ Assert.IsTrue(true);}[TestMethod]public void TestMethod2(){ Assert.IsTrue(true);}
When we run the above two test cases in Visual Studio, we find that only one test case can pass the test, and the other test case will throw the following exception:
Root Cause
The first test case was successfully completed after running the test case. However, an error occurred while initializing the second test case and calling createifnotexist to try to create a cloudtable. From the exception information above, we can see that the error code for this exception is tablebingdeleted.
The error code tells us that, while cleaning up the data in the first test case, calling deleteifexists to delete the cloudtable successfully returns, the delete operation does not end immediately, simply setting a label in the background indicates that the cloudtable needs to be deleted and the result is returned. It may take 40 seconds or more to delete a cloudtable. If we call createifnotexist to re-create the same cloudtable after deleteifexists, the table actually exists and is being deleted, so the re-creation operation cannot be completed.
Solve the problem
In this example, we delete cloudtable only because we need to clear the data left by the previous test. You can delete all data in cloudtable without deleting the entire cloudtable. Deleting data in cloudtable (through tableoperation. delete) is synchronous. If the function returns, azure will ensure that the data is deleted.
If you must delete the entire cloudtable, you must handle the error when creating the cloudtable. The following is a reference code for calling cloudtable. createifnotexists:
[TestInitialize]public void InitializeTest(){ string connectionString = Constant.connectionString; CloudStorageAccount storageAccount = Utilities.GetStorageAccount(connectionString); tableClient = storageAccount.CreateCloudTableClient(); table = tableClient.GetTableReference(tableName); int retryTimes = 0; int maxRetryTimes = 20; StorageException lastException = null; while (retryTimes < maxRetryTimes) { try { table.CreateIfNotExists(); break; } catch (StorageException excep) { var extendedInformation = excep.RequestInformation.ExtendedErrorInformation; var errorCode = extendedInformation.ErrorCode; if (errorCode == "TableBeingDeleted") { retryTimes++; lastException = excep; Thread.Sleep(5 * 1000); // Sleep 5 seconds } else { throw; } } } if(retryTimes == maxRetryTimes && lastException != null) { throw lastException; }}