我知道QueueTrigger
当队列中有新消息可用时,会调用一些东西。然而,这种“框架风格”的 WebJobs 让我很难正确初始化我的环境。
这就是我想自己轮询队列的原因,基本模式是这样的:
var account = CloudStorageAccount.Parse("connectionString");
var client = account.CreateCloudQueueClient();
// Per application initialization stuff goes here
while(true) {
var queue = client.GetQueueReference("myqueue");
var message = queue.GetMessage();
if (message != null) {
// Per message initialization stuff goes here
// Handle message
queue.DeleteMessage(message);
}
else {
Thread.Sleep(10000); // Or some exponential back-off algorithm
}
}
我的问题是,在 WebJob 中连续运行时,这种方法是否存在潜在问题?如果是这样,避免“框架式”WebJobs 的可能替代方法是什么?
编辑
根据 Victor 的要求,这里有一些关于我为什么不想使用这种QueueTrigger
方法的更多信息。基本上有两个原因。
第一个在上面已经提到了,就是框架调用了一个带有QueueTrigger
属性的方法。这意味着我必须将所有初始化都放在该方法中。
我们的 Web 应用程序中有一个两阶段 IoC 容器(每个应用程序和每个请求),我想让 WebJobs 尽可能靠近 Web 应用程序,所以我想使用那个两阶段 IoC在 WebJobs 中也是如此(每个应用程序的 IoC 会进行一些繁重的初始化,然后在所有请求中重用)。这样做的结果是我必须将每个应用程序的容器放在静态变量或单例中,以便我可以从静态QueueTrigger
方法访问它。这是我不愿意做的设计怪癖(IMO,Microsoft 做的太多了,例如,Thread.CurrentCulture
或者HttpContext.Current
- 这真的是一种反模式并且会损害可测试性)。
针对上述情况的完美 WebJobs SDK 将使基础设施(后退计时器、毒物处理等)可作为服务使用,以便主控制流始终保留在应用程序中。这可能适用于 SDK 的所有功能,也可能不可能,我对 SDK 的了解还不够,无法判断。
第二个原因是开发者的便利。我们有一个分布式团队,有时在离线环境中工作。从我在这里和这里阅读的内容来看,不可能使用存储模拟器在本地运行 WebJob 应用程序并让它出列消息。使用我现在采用的自我轮询方法,这就像一个魅力。