locked
ChannelUri is null and ChannelUriUpdated does not fire when populated

    Question

  • My app has been working fine, but suddenly while debugging with device, it was crashing on startup.  I was able to repeat it several times and have found several startling pieces of information that I did not know.  The method HttpNotificationChannel.Open() is Asynchronous!  Wish it was named OpenAsync...  So the Microsoft sample here is absolutely wrong.  Because at the end of the "CreatingANotificationChannel" method, the suggestion is to send the URI to your service -- SendURIToService(myChannel.ChannelUri);.  But, it may never execute because ChannelUri will likely be null, because after calling the Open() there is almost no time allowed for the ChannelUri to populate.  Supposedly, after you call the Open() method, the ChannelUriUpdated event should fire, but I DO NOT see that.  So, I changed to poll for the ChannelUri to populate and set a breakpoint in the ChannelUriUpdated event and even though the ChannelUri populates every time, the event never fires.  I am seeing between 0.5 seconds to 2 seconds before the ChannelUri is actually populated!  Here is some code I ran for this test with associated output... 
     

    1         private void InitializeNotificationChannel()  
    2         {  
    3             // The name of our push channel.  
    4             string channelName = "ChannelName";  
    5  
    6             // Try to find the push channel.  
    7             App.PushChannel = HttpNotificationChannel.Find(channelName);  
    8  
    9             // If the channel was not found, then create a new connection to the push service.  
    10             if (App.PushChannel == null)  
    11             {  
    12                 App.PushChannel = new HttpNotificationChannel(channelName);  
    13  
    14                 // Register for all the events before attempting to open the channel.  
    15                 App.PushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);  
    16                 App.PushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);  
    17  
    18                 App.PushChannel.Open();  
    19             }  
    20             else 
    21             {  
    22                 // The channel was already open, so just register for all the events.  
    23                 App.PushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);  
    24                 App.PushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);  
    25             }  
    26  
    27             try 
    28             {  
    29                 Debug.WriteLine("Channel: " + App.PushChannel.ChannelUri);  
    30                 var start = DateTime.Now;  
    31  
    32                 while (App.PushChannel.ChannelUri == null)  
    33                 {  
    34                     Debug.WriteLine("Waiting");  
    35                 }  
    36  
    37                 Debug.WriteLine("Total milliseconds for ChannelUri to Populate: " + DateTime.Now.Subtract(start).TotalMilliseconds);  
    38  
    39                 if (App.PushChannel.ChannelUri.ToString().Split(new string[] { "://" }, StringSplitOptions.RemoveEmptyEntries).Count() != 2)  
    40                 {  
    41                     Debug.WriteLine("Missing parts");  
    42                     return;  
    43                 }  
    44  
    45                 // Send new Notification channel to service  
    46                 var channel = App.PushChannel.ChannelUri.ToString().Split(new string[] { "://" }, StringSplitOptions.RemoveEmptyEntries)[1];  
    47                 commandQueue.Enqueue("control.svc/settings?NOTIFY:" + App.DeviceID + "=" + channel);  
    48              }  
    49             catch (Exception ex)  
    50             {  
    51                 Debug.WriteLine("Exception after channel open. " + ex.Message);  
    52             }  
    53         } 

    Output:
    1 Channel:   
    2 Waiting  
    3 Waiting  
    4  
    5 ...  
    6  
    7 Waiting  
    8 Total milliseconds for ChannelUri to Populate: 1529 

    If people actually take the Microsoft example, they could easily be missing the channel update or never get it leading to tiles that won't update!  I believe there is a bug in the ChannelUriUpdated event!  And the Open() method should be named with Async! 

    Note: there could be circumstances under which the ChannelUriUpdated event fires.  I have not tried all permutations of Device/Emulator/Connection, but I do believe the behavior I am seeing should never happen.  I no longer trust the ChannelUriUpdated event and will instead use a timer and delegate to poll for the ChannelUri. 

    Note: the code above is just to demonstrate the problem.  It should never be used as it is because it could easily hang the app waiting for a channel. 

    Update: The MSDN example noted above may not be the latest, this being the latest, although it still doesn't change the fact that ChannelUriUpdated is not firing.  And even the updated example will still not work without that event firing reliably after the Open() method. 

    Update2: I had just implemented a timer based polling solution and moved on to working on another issue when out of the blue I hit the breakpoint I had left in the ChannelUriUpdated Event!  So, now I am even more confident that the event handler was set correctly and that ChannelUriUpdated does not fire reliably!  For over 40 minutes it did not fire, then it fires.  Note: my workaround also caught the channel update, so I am sticking with the polling. 

    -Valkyrie-MT
    Monday, January 9, 2012 3:21 AM

All replies

  • Hi ValkyrieTech, did you able to sort out the issue or not. If so please share your code as I am also in the same kind of problem. Things were just working fine successfully but since I updated my device yesterday my channelUri event has stopped working on Phone, but it is working fine in emulater. ... any suggestions....please help....

    I have also posted my issue here

    Thanks
    Khurram
    Sunday, April 29, 2012 9:12 AM
  • I have the same porblem as you. It was ok until i have checked this now. For now  it is working on emulator but i am unable to get chanel uri on device. Any solution for this ?  thanks.
    Thursday, May 10, 2012 11:32 AM
  • 32                 while (App.PushChannel.ChannelUri == null)     
    33                 {     
    34                     Debug.WriteLine("Waiting");     
    35                 }    
     
      You are spinning in a While loop which will block the thread from processing the ChannelUpdated event message.
      If you want to poll the ChannelUri property you should use a DispatcherTimer instead. 
      (... and poll only once every tick, i.e. no While loop.)
    Thursday, May 10, 2012 4:02 PM
  • I have the same porblem as you. It was ok until i have checked this now. For now  it is working on emulator but i am unable to get chanel uri on device. Any solution for this ?  thanks.

    Push notification may not be able to open a channel in certain network configurations. 
    Push notification uses sockets for part of the communication with the push notification server. 

    For example: Using WiFi which requires proxy, or cellular data connection with HTTP only proxy.
    Thursday, May 10, 2012 4:15 PM
  • There are two cases when you will not able to receive channel URI from MPNS
    1. WIFI network connection proxy on
    2. Battery is low and battery saver mode is ON
    Thursday, May 10, 2012 10:52 PM
  • Today without any change on side of device and on code i am able to register and  i am retirivimn chanel from serwer. Generally i believe that it was some kind of problem on Microsoft side.
    Thursday, May 17, 2012 8:13 AM