我可以查询 Azure Web 作业队列吗?

Can I query the Azure web job queue?

我的 Azure Web 应用程序中有两个 Azure Web 作业 运行:

作业 A 的目的是基于两件事触发作业 B:

  1. 作业 B 在过去一小时内未 运行 指定帐号(作为参数从作业 A 传递到作业 B。
  2. 根据数据库确定的一些其他业务逻辑

#2 很简单。我有一个问题是#1。 作业A是否可以查询web作业队列,看作业B是否已经执行?

这是作业 B(已触发):

public class Functions
{
    public static void ProcessQueueMessage([QueueTrigger("triggeredqueue")] string message, TextWriter log)
    {
        var accountId = message;
        //DO STUFF WITH accountId HERE...
    }
 }

这里是工作 A(运行连续)。我在评论中添加了代码以显示我喜欢做什么:

class Program
{
    static void Main()
    {
        while (true)
        {
            var accounts = getAccounts();
            foreach (var account in accounts) {
                if (testOtherBusinessLogic(account)) {
                    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionStringHelper.StorageConnectionString);
                    CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
                    CloudQueue queue = queueClient.GetQueueReference("triggeredqueue");
                    queue.CreateIfNotExists();
                    //THIS IS WHAT IT IS DOING NOW:
                    CloudQueueMessage message = new CloudQueueMessage(account.AccountId);
                    queue.AddMessage(message);
                    //THIS IS WHAT I WOULD LIKE IT TO DO:
                    /* 
                    if (!queue.Any(x => x.RunDate > (DateTime.Now.AddMinutes(-60)) && x.Message == account.AccountId.ToString()) {                          
                        CloudQueueMessage message = new CloudQueueMessage(account.AccountId);
                        queue.AddMessage(message);
                    }
                    */
                }
            }
            System.Threading.Thread.Sleep(7000);
        }
    }
}

Azure 存储队列不支持查询操作。请注意,一旦您的 queuetrigger 运行,触发它的消息将不再在队列中。此外,你的JobB也应该运行不断地监听队列的变化。

我建议您使用table 存储来存储执行日期。试试下面的代码。

// Add table entity class in JobA Program class and JobB Functions class
class MyEntity : TableEntity
{
    public DateTime ExecutionTime { get; set; }
}


//In JobA, achieve what you would like to do 
 var accountId = account.AccountId;
 CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
 CloudTable table = tableClient.GetTableReference("execution");
 table.CreateIfNotExists();

 // table entity use combination of partionkey and rowkey as entity identifier, so I set both of them to accountId
 TableOperation retriveOperation = TableOperation.Retrieve<MyEntity>(accountId, accountId);

 MyEntity retriveEntity = (MyEntity)table.Execute(retriveOperation).Result;

 if (retriveEntity != null)
 {
     if (retriveEntity.ExecutionTime> DateTime.UtcNow.AddMinutes(-60))
     {
         CloudQueueMessage message = new CloudQueueMessage(accountId);
         queue.AddMessage(message);
     }
 }else
 {
     CloudQueueMessage message = new CloudQueueMessage(accountId);
     queue.AddMessage(message);
 }


 //In JobB, add operations to store execution time after business logic 
 //Connection operations omitted, please add by yourself.
 CloudTable table = tableClient.GetTableReference("execution");
 table.CreateIfNotExists();
 TableOperation retriveOperation = TableOperation.Retrieve<MyEntity>(accountId, accountId);
 MyEntity retriveEntity = (MyEntity)table.Execute(retriveOperation).Result;

 if (retriveEntity != null)
 {
      retriveEntity.ExecutionTime = DateTime.UtcNow;
      TableOperation updateOperation = TableOperation.Replace(retriveEntity);
      table.Execute(updateOperation);
 }
 else
 {
      retriveEntity = new MyEntity
      {
           ExecutionTime = DateTime.UtcNow,
           PartitionKey = accountId,
           RowKey = accountId
       };
      TableOperation insertOperation = TableOperation.Insert(retriveEntity);
      table.Execute(insertOperation);
 }

最后的建议,好像没必要用queuetrigger,可以只用JobA来达到目的(DO STUFF WITH accountId直接在JobA中)。