public static bool PollForMessage <T>(string queueName, Func <T, bool> action, int visibilityTimeoutSeconds = 30, Func <T, bool> condition = null) where T : AzureMessage { // Wrap condition in a wrapper function that converts the raw message into the type that condition wants Func <CloudQueueMessage, bool> rawCondition = null; if (condition != null) { rawCondition = rawMessage => condition.Invoke(AzureMessage.FromMessage(rawMessage) as T); } return(PollForMessageRawCondition <T>(queueName, action, visibilityTimeoutSeconds, rawCondition)); }
public static bool PollForMessageRawCondition <T>(string queueName, Func <T, bool> action, int visibilityTimeoutSeconds = 30, Func <CloudQueueMessage, bool> condition = null) where T : AzureMessage { CloudQueue queue = StorageAccount.CreateCloudQueueClient().GetQueueReference(queueName); CloudQueueMessage queueMessage; queue.CreateIfNotExist(); queueMessage = queue.GetMessage(new TimeSpan(0, 0, visibilityTimeoutSeconds)); if (queueMessage == null) { return(false); } T message = AzureMessage.FromMessage(queueMessage) as T; if (condition != null && !condition.Invoke(queueMessage)) { // Force the message to become visible on the queue, because we don't want to process it. See AzureHelperTest.AddThenDeleteMessageTest for a demonstration that this works. queue.AddMessage(queueMessage); queue.DeleteMessage(queueMessage); return(false); } if (!action.Invoke(message)) { return(false); } try { queue.DeleteMessage(queueMessage); } catch (StorageClientException e) { // It took too long to process the message and the visibility timeout expired // See http://blog.smarx.com/posts/deleting-windows-azure-queue-messages-handling-exceptions if (e.ExtendedErrorInformation.ErrorCode == "MessageNotFound") { System.Diagnostics.Trace.WriteLine("Visibility timeout expired: " + e); return(false); } else { throw e; } } return(true); }