locked
Event handler always running twice or more RRS feed

  • Question

  • SL4 Business application VS2010

    I use the private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e) {} event handler to subscribe to a web service.  However when I log out (see LogoutLink_Click method) and then log back in, I get the Authentication_LoggedIn twice, thus subscribing the the web service twice.

    I have tried different things but they don't seem to work as needed.

    It seem to happen when I navigate to another SL page.  Probably because I have the Authentication_LoggedIn event handler in the constructor of my HomePage.

    Any ideas? Thanks

        /// <summary>
        /// Home page for the application.
        /// </summary>
        public partial class Home : Page
        {
            private readonly AuthenticationService authService = WebContext.Current.Authentication;
            private readonly DbDomainContext safeContext = new DbDomainContext();
            private int clientIdRef = 1;  // 1 for debugging
            
            private DBNotificationClient client =
                new DBNotificationClient(new PollingDuplexHttpBinding(),
                        new EndpointAddress("http://localhost:1234/DBNotificationService/DBNotificationService.svc"));
            private Boolean isSubscribed;
                  
            
            /// <summary>
            /// Creates a new <see cref="Home"/> instance.
            /// </summary>
            public Home()
            {
                InitializeComponent();            
    
                this.authService.LoggedIn += this.Authentication_LoggedIn;
                this.authService.LoggedOut += this.Authentication_LoggedOut;
            
    
                // Hide buttons
                if (this.authService.User.Identity.IsAuthenticated != true)
                {
                    showHideButtons(Visibility.Collapsed);
                }
                else
                {
                    // Client
                    if (WebContext.Current.User.IsInRole("client"))
                    {
                        showHideButtons(Visibility.Visible);
                        LogoutLink.Visibility = Visibility.Visible;
                        
                    }
    
                }
                
            }
    
            /// <summary>
            /// Executes when the user navigates to this page.
            /// </summary>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {            
            }
    
            private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
            {
    
                // Client
                if (WebContext.Current.User.IsInRole("client"))
                {
                    showHideButtons(Visibility.Visible);                
                    
                    // Load Client Data            
                    LogoutLink.Visibility = Visibility.Visible;
                    clientHomePageViewDomainDataSource.Load();
    
                    this.InitialisePageFunctionality();
                    
                }
             }
    
            private void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
            {
     
                // Hide buttons
                if (this.authService.User.Identity.IsAuthenticated != true)
                {
                    showHideButtons(Visibility.Collapsed);
                    LogoutLink.Visibility = Visibility.Collapsed;
                }
    
                // Client
                if (WebContext.Current.User.IsInRole("client"))
                {
                    showHideButtons(Visibility.Collapsed);
    
                }
    
            }
    
            // Shows hides buttons based on logins
            private void showHideButtons(Visibility v)
            {
                HistoryButton.Visibility = v;
    
            }
    
            private void HomePageViewDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
            {
    
                if (e.HasError)
                {
                    System.Windows.MessageBox.Show(e.Error.ToString(), 
                        "Load Error", System.Windows.MessageBoxButton.OK);
                    e.MarkErrorAsHandled();
                }
                        
            }
    
            private void OnInvokeCompleted(InvokeOperation<int> invOp)
            {
    
                if (invOp.HasError)
                {
                    MessageBox.Show(string.Format("Action Failed: {0}", invOp.Error.Message));
                    invOp.MarkErrorAsHandled();
                }
                
            }
    
            /// <summary>
            /// Initialises the page functionality.
            /// </summary>
            private void InitialisePageFunctionality()
            {
    
                client.SendNotificationToClientsReceived += 
                    new EventHandler<SendNotificationToClientsReceivedEventArgs>
                        (client_SendNotificationToClientsReceived);
              
                    this.Subscribe(); // make the browser (instance) known to server
                    MessageBox.Show("suscribed");
    
            }
    
            private void client_SendNotificationToClientsReceived(object sender, SendNotificationToClientsReceivedEventArgs e)
            {
                if (e.sender != null) UpdatedClientReceived(e.clientId, e.sender); // something to process
            }
    
    
            /// <summary>
            /// Update with new, updated or deleted client data.
            /// </summary>
            private void UpdatedClientReceived(int clientId, string sender)
            { 
    
                if (clientId == clientIdRef)
                {
                    // Show notification
                }
    
            }
    
    
    
            /// <summary>
            /// Subscribes this instance of the browser,
            /// </summary>
            private void Subscribe()
            {
                client.SubscribeToNotificationsCompleted += 
                    new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>
                        (client_SubscribeToNotificationsCompleted);
                client.SubscribeToNotificationsAsync();
    
            }
    
            private void client_SubscribeToNotificationsCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
             
            }
    
            /// <summary>
            /// Unsubscribes this instance of the browser
            /// </summary>
            private void Unsubscribe()
            {
                if (client != null)
                {
                    
                    client.UnsubscribeToNotificationsCompleted += (sender, e) => { };
                    
                    client.UnsubscribeToNotificationsAsync();
    
                }
                
            }
    
            
            // Logout Link
            private void LogoutLink_Click(object sender, RoutedEventArgs e)
            {
                // Unsubscribe
                this.Unsubscribe();
                this.isSubscribed = false;
    
                this.authService.Logout(false);
    
                
                LogoutLink.Visibility = Visibility.Collapsed;
                showHideButtons(Visibility.Collapsed);
    
                // Remove event handlers
                client.SubscribeToNotificationsCompleted -= client_SubscribeToNotificationsCompleted;
                client.SendNotificationToClientsReceived -= client_SendNotificationToClientsReceived;
                
                // Tried this but didn't work when navigating away from the Home page
                //authService.LoggedIn -= Authentication_LoggedIn;
                //authService.LoggedOut -= Authentication_LoggedOut;
            }
    
            
        }


    Friday, March 4, 2011 9:30 AM

Answers

  • You have to declare all the methods( that are called when the Async operations completed ), insite the constructor, which initializes the completed event handler's methods only once. More importantly, they should appear after the initialization of the service reference.

    For Examble,                    

    public partial class Home:UserControl           {

    AuthenticationService authService;
    public Home()
    { authService=new AuthenticationService();
    authService.LoggedInCompleted+=Authendication_LoggedIn;
    }

    You have that problem, because whenever you call the Async opation, you add a enent handler. So have to make a single
    event handler by decalre it inside the Consturtor.

    Thanks,
    Friday, March 4, 2011 9:58 AM

All replies

  • You have to declare all the methods( that are called when the Async operations completed ), insite the constructor, which initializes the completed event handler's methods only once. More importantly, they should appear after the initialization of the service reference.

    For Examble,                    

    public partial class Home:UserControl           {

    AuthenticationService authService;
    public Home()
    { authService=new AuthenticationService();
    authService.LoggedInCompleted+=Authendication_LoggedIn;
    }

    You have that problem, because whenever you call the Async opation, you add a enent handler. So have to make a single
    event handler by decalre it inside the Consturtor.

    Thanks,
    Friday, March 4, 2011 9:58 AM
  • cool thanks

    Friday, March 4, 2011 11:01 AM