我嘗試在實時Azure存儲隊列中使用單元測試時遇到了一些困難,並且不斷編寫更簡單更簡單的示例來嘗試隔離問題。簡而言之,這裏是似乎正在發生的事情:單元測試時,爲什麼azure存儲隊列訪問速度太慢?
隊列訪問顯然(並且適當)是延遲加載的。但在我的MVC應用程序中,當我真的需要訪問隊列時(在我調用CloudQueue.Exists方法的情況下),它非常快。不到十分之一秒。但是,在單元測試環境中運行的非常相同的代碼大約需要25秒。
我不明白爲什麼應該有這種差異,所以我做了一個簡單的控制檯應用程序,它寫入了一些內容,然後從Azure隊列中讀取它。控制檯應用程序在第一次運行時也需要25秒 - 後續運行需要大約2.5秒。
而現在的真正奇怪的行爲。我創建了一個包含三個項目的Visual Studio 2012解決方案 - 一個MVC應用程序,一個控制檯應用程序和一個單元測試項目。所有三者都調用相同的靜態方法來檢查隊列的存在,如果它不存在則創建它,向它寫入一些數據並從中讀取一些數據。我在這個方法中調用了CloudQueue.Exists。這是交易。當從MVC應用程序調用該方法時,無論隊列是否存在,CloudQueue.Exists方法都會在大約十分之一秒內持續完成。當從控制檯應用程序調用該方法時,第一次調用該方法需要25秒,後續時間大約需要2.5秒。當從單元測試中調用該方法時,它始終需要25秒。
更多信息:恰好當我創建這個虛擬解決方案時,碰巧把我的靜態方法(QueueTest)放在控制檯應用程序中。這是奇怪的 - 如果我將Visual Studio中的默認啓動項目設置爲控制檯應用程序,那麼單元測試突然需要2.5秒。但是,如果我將Visual Studio中的啓動項目設置爲MVC應用程序(或單元測試項目),那麼單元測試需要25秒!
所以......有沒有人有這方面的理論?我很困惑。下面
代碼如下:
控制檯應用程序:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(QueueTest("my-console-queue", "Console Test"));
}
public static string QueueTest(string queueName, string message)
{
string connectionString = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference(queueName);
DateTime beforeTime = DateTime.Now;
bool doesExist = queue.Exists();
DateTime afterTime = DateTime.Now;
TimeSpan ts = afterTime - beforeTime;
if (!doesExist)
{
queue.Create();
}
CloudQueueMessage qAddMessage = new CloudQueueMessage(message);
queue.AddMessage(qAddMessage);
CloudQueueMessage qGetmessage = queue.GetMessage();
string response = String.Format("{0} ({1} seconds)", qGetmessage.AsString, ts.TotalSeconds);
return response;
}
}
MVC應用程序(家庭控制器):
public class HomeController : Controller
{
public ActionResult Index()
{
return Content(Program.QueueTest("my-mvc-queue", "Mvc Test"));
}
}
單位測試方法:(注意,目前預期失敗!)
[TestClass]
public class QueueUnitTests
{
[TestMethod]
public void CanWriteToAndReadFromQueue()
{
//Arrange
string qName = "my-unit-queue";
string message = "test message";
//Act
string result = Program.QueueTest(qName, message);
//Assert
Assert.IsTrue(String.CompareOrdinal(result,message)==0);
}
}
當然,洞察力是非常感謝。
感謝。似乎很好。我不能說我完全理解這是什麼,插入這段代碼是否有缺點,但我會尋找它。如果你有更多的話要說,將不勝感激。大幫忙! –
AND ...因爲我的最終目標是一個DLL(要在內部使用,而不是針對大衆),我不想對用戶的代理設置做出假設。添加@kwill建議的代碼很有用。我嘗試了另一個建議,在.config文件中爲「默認代理」設置「useDefaultCreditials」,但這沒有任何作用。所以,也許我需要將自己的部分添加到.config文件並保留給用戶?這聽起來並不好...... –
如果您正在構建DLL,那麼您不想更改代理設置。您可以將其留給用戶(或應用程序開發人員)來管理應用程序的代理設置。將代碼保留用於測試目的是好的,但在創建其他人將使用的構建之前,應將其刪除。 – kwill