0

我嘗試在實時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); 
    } 
} 

當然,洞察力是非常感謝。

回答

1

我懷疑這與Azure隊列無關,而是與.NET嘗試確定您的代理設置有關。如果你進行一些其他隨機System.Net調用而不是對隊列存儲的調用,會發生什麼?

試試下面這行代碼在您的應用程序的開頭:

System.Net.WebRequest.DefaultWebProxy = null; 
+0

感謝。似乎很好。我不能說我完全理解這是什麼,插入這段代碼是否有缺點,但我會尋找它。如果你有更多的話要說,將不勝感激。大幫忙! –

+0

AND ...因爲我的最終目標是一個DLL(要在內部使用,而不是針對大衆),我不想對用戶的代理設置做出假設。添加@kwill建議的代碼很有用。我嘗試了另一個建議,在.config文件中爲「默認代理」設置「useDefaultCreditials」,但這沒有任何作用。所以,也許我需要將自己的部分添加到.config文件並保留給用戶?這聽起來並不好...... –

+0

如果您正在構建DLL,那麼您不想更改代理設置。您可以將其留給用戶(或應用程序開發人員)來管理應用程序的代理設置。將代碼保留用於測試目的是好的,但在創建其他人將使用的構建之前,應將其刪除。 – kwill

相關問題