我刚刚针对我的 Azure 代码运行了 Visual Studio 2010 线程分析器,发现出现了很多争用。我的代码被阻塞的次数比运行时的次数还要多!
我的工作线程中根本没有自定义线程逻辑。这是一个简单的 While 循环,它询问各个队列是否有工作。我创建了 QueueRepositoryClass 的一个实例,然后调用 GetQueueMessage 函数。
看起来由于某种原因,多个线程正在调用我的 GetQueueMessage 方法并使用相同的 queueClient 实例。也许这是我使用 CloudStorageAccount 对象的结果?或者是 CreateCloudQueueClient 扩展方法?
最佳答案
如果没有看到调用代码,这在一定程度上是猜测,但看起来您正在一个相当紧密的循环中调用 GetMessage()。 GetMessage 是同步调用,这样做会使该特定线程在等待队列响应时阻塞自身(其他线程继续运行)。在探查器中,这看起来非常糟糕,因为循环逻辑的其余部分执行得如此之快(即您花费一两毫秒执行代码并花费 50 毫秒获取消息,看起来就像那样)。
还有一点需要注意的是,出于以下几个原因,您需要非常小心地查询紧密循环中的队列:
1) 虽然每次 Tx 费用很小,但它不是 0。我通常建议一些退避逻辑 - 即如果队列为空,则等待 100ms,然后再次检查。清空两次,回退到 500 毫秒等。显然,您必须在这与您想要的用户体验之间取得平衡。
2) 如果您最终扩展应用程序 - 您实际上对队列发起了 DoS 攻击。 100 个实例都在紧密循环中冲击队列确实会损害性能。
拍拍
关于visual-studio-2010 - 是什么导致我的 Azure 队列代码出现线程争用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3344723/