2009-05-16 4 views
0

C# 2005Exception d'invocation utilisant AutoResetEvent

J'utilise un agent d'arrière-plan pour traiter certaines informations de connexion. Cependant, le travailleur en arrière-plan doit s'arrêter et attendre que 2 événements se produisent. Une fois que celles-ci sont terminées, le travailleur en arrière-plan peut terminer son travail. Ce sont des rappels qui appellent la méthode Set() de l'AutoResetEvent. Donc, j'utilise AutoResetEvent pour définir quand ces 2 événements sont terminés. Cependant, j'ai semblé obtenir ce message d'erreur: "Exception a été levée par la cible d'une invocation."

Et l'exception interne L'index était hors de portée. Doit être non négatif et inférieur à la taille de la collection. Nom du paramètre:. index »

L'exception se déclenche généralement lorsque le succès de l'enregistrement laisse le champ

Un grand merci pour tous les conseils

Le code pour le travailleur de fond

// Waiting for 'Account in use' and 'Register success or failure' 
AutoResetEvent[] loginWaitEvents = new AutoResetEvent[] 
{ 
     new AutoResetEvent(false), 
     new AutoResetEvent(false) 
}; 

private void bgwProcessLogin_DoWork(object sender, DoWorkEventArgs e) 
{ 
     Console.WriteLine("Wait until event is set or timeout"); 
     loginWaitEvents[0].WaitOne(3000, true); 

     if (this.accountInUseFlag) 
     { 
       if (this.lblRegistering.InvokeRequired) 
       { 
        ///this.lblRegistering.Invoke(new UpdateRegisterLabelDelegate(this.UpdateRegisterLabel), "Account in use"); 
       } 
       else 
       { 
        ///this.lblRegistering.Text = "Account in use"; 
       } 
       // Failed attemp 
       e.Cancel = true; 
       // Reset flag 
       //this.accountInUseFlag = false; 
       return; 
     } 
     else 
     { 
       // Report current progress 
       //this.bgwProcessLogin.ReportProgress(7, "Account accepted"); 
     } 

     Console.WriteLine("Just Wait the result of successfull login or not"); 
     loginWaitEvents[1].WaitOne(); 
     Console.WriteLine("Results for login registionSuccess: [ " + registerSuccess + " ]"); 

     if (this.registerSuccess) 
     { 
       // Report current progress 
       //this.bgwProcessLogin.ReportProgress(7, "Register Succesfull"); 
       // Reset flag 
       //this.registerSuccess = false; 
     } 
     else 
     { 
       if (this.lblRegistering.InvokeRequired) 
       { 
        //this.lblRegistering.Invoke(new UpdateRegisterLabelDelegate(this.UpdateRegisterLabel), "Failed to register"); 
       } 
       else 
       { 
        // this.lblRegistering.Text = "Failed to register"; 
       } 
       // Failed attemp 
       e.Cancel = true;    
       return; 
     } 
} 

// Wait for the callback to set the AutoResetEvent 

// Error sometimes happens when the function leaves scope. 
private void VaxSIPUserAgentOCX_OnSuccessToRegister(object sender, EventArgs e) 
{ 
     Console.WriteLine("OnSuccessToRegister() [ Registered successfully ]"); 
     this.registerSuccess = true; 
     this.loginWaitEvents[1].Set(); 
} 


// If the flag is not set, then just time out after 3 seconds for the first LoginWaitEvent.waitOne(3000, true) 
private void VaxSIPUserAgentOCX_OnIncomingDiagnostic(object sender, AxVAXSIPUSERAGENTOCXLib._DVaxSIPUserAgentOCXEvents_OnIncomingDiagnosticEvent e) 
{ 
     string messageSip = e.msgSIP; 

     //Indicates that a user is already logged on (Accout in use). 
     string sipErrorCode = "600 User Found"; 
     if (messageSip.Contains(sipErrorCode)) 
     { 
      // Set flag for account in use 
      this.accountInUseFlag = true; 
      Console.WriteLine("OnIncomingDiagnostic() WaitEvent.Set() accountInUseFlag: " + this.accountInUseFlag); 
      loginWaitEvents[0].Set(); 
     } 
} 
+0

Que fait UpdateRegisterLabel? Est-ce que cela ne fait que placer le texte sur un contrôle d'étiquette? –

Répondre

1

Il est.. probablement une erreur d'indexation dans la méthode UpdateRegisterLabel

Obtenir une trace de pile à partir de l'exception interne, il devrait vous pointer plus étroitement à où il est.

+0

Bonjour, j'ai résolu mon problème. C'était quelque chose dans le RunWorkercompleted. Cependant, il y a une chose de plus. Les fonctions registerSuccess et AccountInUse sont globales car elles ont été accédées à partir de 2 threads différents. Serait-il préférable de les verrouiller? Merci beaucoup – ant2009

+0

Vous n'avez pas besoin de verrouiller les booléens, mais vous pouvez les marquer comme volatiles pour vous assurer que chaque thread a toujours la valeur la plus à jour. –