1

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

  • 作业 A - 连续运行
  • 作业 B - 触发

Job A 的目的是基于两件事触发 Job 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);
        }
    }
}
4

1 回答 1

2

Azure 存储队列不支持查询操作。请注意,一旦您的 queuetrigger 运行,触发它的消息将不再在队列中。此外,您的 JobB 还应该持续运行以侦听队列中的更改。

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

// 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 中)。

于 2018-05-10T07:05:45.420 回答