Skip to content

The collection has been marked as complete with regards to additions in APNSBroker Queue Notification #763

Closed

Description

@emysa341

HI @Redth

Pushsharp version 4.0

I am getting an exception "System.InvalidOperationException: The collection has been marked as complete with regards to additions". After searching for hours I came to know this is because the queue notification do not accepts the same Id when its called 2nd time. My problem is let say if this service is running I send a notification to User-token-1 and after few seconds if I send the notification to same user with same User-token-1 then I get the exception.

To produce this issue just send the notification two times to same user but calling this code function two times not in single custom message. I am sending it two times because I have a requirement to send multiple notification to same user but not in single push message but a different push message. To give an idea how this error can be reproduces please understand the following situation and please ignore my custom variables. Even though if I ignore this like calling SendPushMessageToEmployees only one time then later if I need to send notification to same user after few minutes on same running service then I will get same exception.

main()
{
          SendPushMessageToEmployees(MyCustomMessage);
          SendPushMessageToEmployees(MyCustomMessage);
}

 public void SendNotification(List<PushMessage> pushMessages)
        {
            try 
            {
                apnsBroker.Start();
                foreach (PushMessage message in pushMessages)
                {
                    if (!String.IsNullOrEmpty(message.DeviceId) )
                    {
                        apnsBroker.QueueNotification(new ApnsNotification
                        {
                            DeviceToken = message.DeviceId,
                            Payload = JObject.Parse("{\"aps\":{\"badge\":0,\"alert\":'" + message.Message + "',\"Workflow\":'" + message.Message + "'}}")
                        });
                    }
                }
                apnsBroker.Stop(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0}",ex.Message);
            }
        }

Exception : System.InvalidOperationException: The collection has been marked as complete with regards to additions.
StackTrace:
System.Collections.Concurrent.BlockingCollection1.TryAddWithNoTimeValidation(T item, Int32 millisecondsTimeout, CancellationToken cancellationToken) at PushSharp.Core.ServiceBroker1.QueueNotification(TNotification notification)

Class in my project

public  class  AppleServiceBroker : IServiceBroker 
{
    private ApnsServiceBroker apnsBroker;
    public AppleServiceBroker()
    {
        if (apnsBroker == null)
        {
           var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox,
             "c:/Web_124/myplano/myplanoCommunication/Content/myplanoPushNotification.p12", "MyPassword");

            apnsBroker = new ApnsServiceBroker(config);

            // Wire up events
            apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
            {
                aggregateEx.Handle(ex =>
                {
                    if (ex is ApnsNotificationException)
                    {
                        var notificationException = (ApnsNotificationException)ex;
                        var apnsNotification = notificationException.Notification;
                        var statusCode = notificationException.ErrorStatusCode;
                        Console.WriteLine("Apple Notification Failed:  ID= " + apnsNotification.Identifier + " Code= " + statusCode);
                    }
                    else
                    {
                        Console.WriteLine("Apple Notification Failed for some unknown reason : " + ex.InnerException);
                    }

                    return true;
                });
            };
        }
    }


    /// <summary>
    /// Sends notification to apple servers
    /// </summary>
    /// <param name="pushMessages">List of push messages</param>
    public void SendNotification(List<PushMessage> pushMessages)
    {
        try 
        {
            apnsBroker.OnNotificationSucceeded += (notification) =>
            {
                Console.WriteLine("Apple Notification Sent!");
            };
            apnsBroker.Start();

            foreach (PushMessage message in pushMessages)
            {
                if (!String.IsNullOrEmpty(message.DeviceId) )
                {
                    apnsBroker.QueueNotification(new ApnsNotification
                    {
                        DeviceToken = message.DeviceId,
                        Payload = JObject.Parse("{\"aps\":{\"badge\":0,\"alert\":'" + message.Message + "',\"Workflow\":'" + message.Message + "'}}")
                    });
                }

            }
            apnsBroker.Stop(true);

        }
        catch (Exception ex)
        {
            Console.WriteLine("{0}",ex.Message);
        }
    }
}

`

Regards
Ammad

Activity

  1. emysa341 commented on Oct 26, 2016

    @emysa341
    Author

    The exception magically disappeared. I manually downloaded the source code of push sharp. Instead of targeting Nuget package. I reference the pushsharp.core and pushsharp.Apple from the solution and I was unable to reproduce the same issue. The solution was working fine without issues with local project reference in solution. I thought may be its problem with pushsharp Nuget package.

    Then I delete the pushsharp.core and pushsharp.Apple projects from solution and then again downloaded and referenced the PushSharp nuget package. This time it worked fine without the above exception "System.InvalidOperationException: The collection has been marked as complete with regards to additions".

  2. ranouf commented on Mar 7, 2018

    @ranouf

    I have the same error too ...

  3. NingenUA commented on Mar 29, 2018

    @NingenUA

    @ranouf did you resolve this issues?

  4. cvocvo commented on Aug 1, 2018

    @cvocvo

    Also have the same error

  5. Malba0 commented on Oct 16, 2018

    @Malba0

    For people who have similar problems (this was my issue and fix).

    ApnsServiceBroker contains a BlockingCollection which is locked up when the broker is stopped. As the broker is stopped no new notifications can be added to the collection to be sent out. After the broker is stopped you will have to re-initialise it before using it again (new ApnsServiceBroker).

    It is an indication that the way you are starting and stopping the broker is not fit for the purpose you want to use it for. Start the service with the Broker initialisation and Stop it when you are wrapping up/closing down/during destruction.

  6. cvocvo commented on Dec 14, 2018

    @cvocvo

    @Malba0 Could you share your code? I'm still running into this even after checking if it's null.

    Here's what I'm doing:

    public void SendNotifications(IEnumerable<Notification> notifications)
    		{
    			if (notifications == null)
    			{
    				throw new ArgumentNullException(nameof(notifications));
    			}
    
    			if (!notifications.Any())
    			{
    				return;
    			}
    
    			var gcmBroker = GetGcmBroker();
    			var apnsBroker = GetApnsBroker();
    			gcmBroker.Start();
    			apnsBroker.Start();
    
                foreach (var notification in notifications)
    			{
    				var memberDevices = _deviceLogic.GetDevices(notification.MemberId);
    				foreach (var device in memberDevices)
    				{
    					if (device.Vendor == DeviceVendor.Apple)
    					{
                            if (apnsBroker == null) //Implying that during the last loop that this potentially closed/stopped
                            {
                                apnsBroker = GetApnsBroker();
                                apnsBroker.Start();
                            }
    						var apnsNotification = FormatAPNSNotification(notification, device, 0);
    						apnsBroker.QueueNotification(apnsNotification);
    					}
    					else if (device.Vendor == DeviceVendor.Google)
    					{
                            if (gcmBroker == null) //Implying that during the last loop that this potentially closed/stopped
                            {
                                gcmBroker = GetGcmBroker();
                                gcmBroker.Start();
                            }
                            var gcmNotification = FormatGCMNotification(notification, device);
    						gcmBroker.QueueNotification(gcmNotification);
    					}
    					else
    					{
    						continue;
    					}
    				}
    			}
    
    			gcmBroker.Stop();
    			apnsBroker.Stop();
    		}
    
  7. Franco-Vera commented on Jun 30, 2020

    @Franco-Vera

    hi,

    i have the same problem. About 10% of daily push notifications are getting this error. until now i think is aleatory... any suggestion?

    context: this a webservices than just send 1 notification for every call. and for the same device sometimes works and sometimes fails.

    Mensaje: The collection has been marked as complete with regards to additions.
    StackTrace: at System.Collections.Concurrent.BlockingCollection1.TryAddWithNoTimeValidation(T item, Int32 millisecondsTimeout, CancellationToken cancellationToken) at PushSharp.Core.ServiceBroker1.QueueNotification(TNotification notification)
    at Connection_Push

    EDIT:
    By doing many tests I was able to verify that the error occurs when I run the service many times in a very short time.

    For example, running the service every one second is no problem, but 10 times in one second the error is generated.

    Is it an IIS or pusharp problem ??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions