private void Begin <T>(Action <T> receiveHandler, SubscriptionClient subscriptionClient) { Debug.WriteLine("Calling BeginReceive"); subscriptionClient.BeginReceive( TimeSpan.FromMinutes(5), (cb) => ProcessBrokeredMessage(receiveHandler, subscriptionClient, cb), null); }
//private SubscriptionClient _subscriptionClient = null; //private string _entityPath = null; //public QueueCacheDependency(string key, string guid, TokenProvider tokenProvider, Uri uri, string queueName) //{ // _key = key; // _guid = guid; // //_tokenProvider = tokenProvider; // //_uri = uri; // //_entityPath = entityPath; // var factory = MessagingFactory.Create(uri, tokenProvider); // _receiver = factory.CreateMessageReceiver(queueName); // WaitCallback callback = new WaitCallback(WaitForMessage); // ThreadPool.QueueUserWorkItem(callback); //} public QueueCacheDependency(string key, SubscriptionClient subscriptionClient, string crc) { Trace.TraceInformation("QueueCacheDependency created: {0}", key); //_subscriptionClient = subscriptionClient; //_guid = guid; _key = key; _crc = crc; subscriptionClient.BeginReceive( TimeSpan.MaxValue, ReceiveDone, subscriptionClient ); }
private void Begin <T>(Action <T> receiveHandler, SubscriptionClient subscriptionClient) { subscriptionClient.BeginReceive( TimeSpan.FromMinutes(5), (cb) => { var brokeredMessage = subscriptionClient.EndReceive(cb); if (brokeredMessage != null) { var messageData = brokeredMessage.GetBody <T>(); receiveHandler(messageData); Begin <T>(receiveHandler, subscriptionClient); } }, null); }
public void StartReceiving(ReceiverCallback callback, SubscriptionClient subscriptionClient, TimeSpan waitTime) { _subscriptionClient = subscriptionClient; //TODO: Find a way to do this now that subscription client is moved to the subscriber //if (_subscriptionClient != null) // we already have a subscription // throw new InvalidOperationException("Already Receiving. Stop previous operation first"); if (_subscriptionClient == null) // we already have a subscription { throw new InvalidOperationException("Subscription Client was not set."); } _receiverCallback = callback; // make initial async call _asyncResult = _subscriptionClient.BeginReceive(waitTime, ReceiveDone, _subscriptionClient); }
public void ReceiveDone(IAsyncResult result) { if (result != null) { var tmpClient = result.AsyncState as SubscriptionClient; if (tmpClient != null) { var brokeredMessage = tmpClient.EndReceive(result); if (brokeredMessage != null) { //TODO: Handle both peeklock and receiveanddelete modes brokeredMessage.Complete(); var tmpMessage = brokeredMessage.GetBody <NotificationMessage>(); #region translate the property back into a type var tmpType = NotificationMessageType.All; if (brokeredMessage.Properties[MessagePropertyType].ToString().Equals(NotificationMessageType.Important.ToString())) { tmpType = NotificationMessageType.Important; } else if (brokeredMessage.Properties[MessagePropertyType].ToString().Equals(NotificationMessageType.Unimportant.ToString())) { tmpType = NotificationMessageType.Unimportant; } #endregion _receiverCallback(tmpMessage, tmpType); } } } // do receive for next message if (_subscriptionClient != null) { _asyncResult = _subscriptionClient.BeginReceive(ReceiveDone, _subscriptionClient); } }
public IAsyncResult BeginReceive(TimeSpan serverWaitTime, AsyncCallback callback, object state) { return(client.BeginReceive(serverWaitTime, callback, state)); }
private static void RunLoop() { MessagingFactory factory = MessagingFactory.Create(); SubscriptionClient auditSubscriptionClient = factory.CreateSubscriptionClient("IssueTrackingTopic", "AuditSubscription", ReceiveMode.ReceiveAndDelete); var retryPolicy = new RetryPolicy <ServiceBusTransientErrorDetectionStrategy>(RetryStrategy.DefaultClientRetryCount); var waitTimeout = TimeSpan.FromSeconds(10); // Declare an action acting as a callback whenever a message arrives on a queue. AsyncCallback completeReceive = null; // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages. Action <Exception> recoverReceive = null; // Declare a cancellation token that is used to signal an exit from the receive loop. var cts = new CancellationTokenSource(); // Declare an action implementing the main processing logic for received messages. Action <BrokeredMessage> processMessage = ((msg) => { // Put your custom processing logic here. DO NOT swallow any exceptions. Console.WriteLine(msg.Properties["HorseId"]); }); // Declare an action responsible for the core operations in the message receive loop. Action receiveMessage = (() => { // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion. retryPolicy.ExecuteAction ( (cb) => { // Start receiving a new message asynchronously. auditSubscriptionClient.BeginReceive(waitTimeout, cb, null); }, (ar) => { // Make sure we are not told to stop receiving while we were waiting for a new message. if (!cts.IsCancellationRequested) { // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy. BrokeredMessage msg = auditSubscriptionClient.EndReceive(ar); // Check if we actually received any messages. if (msg != null) { // Make sure we are not told to stop receiving while we were waiting for a new message. if (!cts.IsCancellationRequested) { try { // Process the received message. processMessage(msg); // With PeekLock mode, we should mark the processed message as completed. if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock) { // Mark brokered message as completed at which point it's removed from the queue. msg.Complete(); } } catch { // With PeekLock mode, we should mark the failed message as abandoned. if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock) { // Abandons a brokered message. This will cause Service Bus to unlock the message and make it available // to be received again, either by the same consumer or by another completing consumer. msg.Abandon(); } // Re-throw the exception so that we can report it in the fault handler. throw; } finally { // Ensure that any resources allocated by a BrokeredMessage instance are released. msg.Dispose(); } } else { // If we were told to stop processing, the current message needs to be unlocked and return back to the queue. if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock) { msg.Abandon(); } } } } // Invoke a custom callback method to indicate that we have completed an iteration in the message receive loop. completeReceive(ar); }, () => { Console.WriteLine("Success Handler"); }, (ex) => { // Invoke a custom action to indicate that we have encountered an exception and // need further decision as to whether to continue receiving messages. recoverReceive(ex); }); }); // Initialize a custom action acting as a callback whenever a message arrives on a queue. completeReceive = ((ar) => { if (!cts.IsCancellationRequested) { // Continue receiving and processing new messages until we are told to stop. receiveMessage(); } }); // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages. recoverReceive = ((ex) => { // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally. Console.WriteLine(ex.Message); if (!cts.IsCancellationRequested) { // Continue receiving and processing new messages until we are told to stop regardless of any exceptions. receiveMessage(); } }); // Start receiving messages asynchronously. receiveMessage(); // Perform any other work. Message will keep arriving asynchronously while we are busy doing something else. // Stop the message receive loop gracefully. cts.Cancel(); }
/// <summary> /// Receives the messages in an endless asynchronous loop. /// </summary> private void ReceiveMessages(CancellationToken cancellationToken) { // Declare an action to receive the next message in the queue or end if cancelled. Action receiveNext = null; // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages. Action <Exception> recoverReceive = null; // Declare an action responsible for the core operations in the message receive loop. Action receiveMessage = () => { // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion. receiveRetryPolicy.ExecuteAction ( cb => { // Start receiving a new message asynchronously. client.BeginReceive(ReceiveLongPollingTimeout, cb, null); }, ar => { // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy. try { return(client.EndReceive(ar)); } catch (TimeoutException) { // TimeoutException is not just transient but completely expected in this case, so not relying on Topaz to retry return(null); } }, msg => { // Process the message once it was successfully received if (processInParallel) { // Continue receiving and processing new messages asynchronously Task.Factory.StartNew(receiveNext); } // Check if we actually received any messages. if (msg != null) { var roundtripStopwatch = Stopwatch.StartNew(); long schedulingElapsedMilliseconds = 0; long processingElapsedMilliseconds = 0; Task.Factory.StartNew(() => { var releaseAction = MessageReleaseAction.AbandonMessage; try { instrumentation.MessageReceived(); schedulingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds; // Make sure the process was told to stop receiving while it was waiting for a new message. if (!cancellationToken.IsCancellationRequested) { try { try { // Process the received message. releaseAction = InvokeMessageHandler(msg); processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds; instrumentation.MessageProcessed(releaseAction.Kind == MessageReleaseActionKind.Complete, processingElapsedMilliseconds); } catch { processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds; instrumentation.MessageProcessed(false, processingElapsedMilliseconds); throw; } } finally { if (roundtripStopwatch.Elapsed > TimeSpan.FromSeconds(45)) { dynamicThrottling.Penalize(); } } } } finally { // Ensure that any resources allocated by a BrokeredMessage instance are released. ReleaseMessage(msg, releaseAction, processingElapsedMilliseconds, schedulingElapsedMilliseconds, roundtripStopwatch); } if (!processInParallel) { // Continue receiving and processing new messages until told to stop. receiveNext.Invoke(); } }); } else { dynamicThrottling.NotifyWorkCompleted(); if (!processInParallel) { // Continue receiving and processing new messages until told to stop. receiveNext.Invoke(); } } }, ex => { // Invoke a custom action to indicate that we have encountered an exception and // need further decision as to whether to continue receiving messages. recoverReceive.Invoke(ex); }); }; // Initialize an action to receive the next message in the queue or end if cancelled. receiveNext = () => { dynamicThrottling.WaitUntilAllowedParallelism(cancellationToken); if (!cancellationToken.IsCancellationRequested) { dynamicThrottling.NotifyWorkStarted(); // Continue receiving and processing new messages until told to stop. receiveMessage.Invoke(); } }; // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages. recoverReceive = ex => { // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally. Trace.TraceError("An unrecoverable error occurred while trying to receive a new message from subscription {1}:\r\n{0}", ex, subscription); dynamicThrottling.NotifyWorkCompletedWithError(); if (!cancellationToken.IsCancellationRequested) { // Continue receiving and processing new messages until told to stop regardless of any exceptions. TaskEx.Delay(10000).ContinueWith(t => receiveMessage.Invoke()); } }; // Start receiving messages asynchronously. receiveNext.Invoke(); }