質問

I ran into some difficulty trying to use unit testing with live Azure Storage Queues, and kept writing simpler and simpler examples to try and isolate the problem. In a nutshell, here is what seems to be happening:

  • Queue access is clearly (and appropriately) lazy-loaded. In my MVC app though, when I get to REALLY need to access the queue (in my case when I call the CloudQueue.Exists method) it is pretty fast. Less than one tenth of a second. However, the VERY same code, when run in the context of a unit test takes about 25 seconds.

  • I don't understand why there should be this difference, so I made a simple console app that writes something and then reads it from an Azure queue. The console app also takes 25 seconds the first time it is run -- on subsequent runs it takes about 2.5 seconds.

  • And now for the really weird behavior. I created a Visual Studio 2012 solution with three projects -- one MVC app, one Console app, and one Unit Test project. All three call the same static method which checks for the existence of a queue, creates it if it doesn't exist, writes some data to it and reads some data from it. I have put a timer on the call to CloudQueue.Exists in that method. And here is the deal. When the method is called from the MVC app, the CloudQueue.Exists method consistently completes in about one tenth of a second, whether or not the queue actually does exist. When the method is called from the console app, the first time it is called it takes 25 seconds, and subsequent times it takes about 2.5 seconds. When the method is called from the Unit Test, it consistently takes 25 seconds.

  • More info: It so happens that when I create this dummy solution, I happened to put my static method (QueueTest) in the console app. Here is what is weird -- if I set the default startup project in Visual Studio to the Console App, then the Unit Test suddenly takes 2.5 seconds. But if I set the startup project in Visual Studio to the MVC app (or to the Unit Test project) then the Unit test takes 25 seconds!

So.... does anyone have a theory of what is going on here? I am baffled.

Code follows below:

Console App:

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 App (Home Controller):

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return Content(Program.QueueTest("my-mvc-queue", "Mvc Test"));
    }
}

Unit Test Method: (Note, currently expected to fail!)

[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);
    }
}

Of course insight is greatly appreciated.

役に立ちましたか?

解決

I suspect this has nothing to do with Azure queues, but rather with .NET trying to determine your proxy settings. What happens if you make some other random System.Net call instead of the call to queue storage?

Try this line of code at the beginning of your app:

   System.Net.WebRequest.DefaultWebProxy = null;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top