2009-11-17 4 views
0

J'ai ce code qui semble assez simple mais l'AutoResetEvent n'est jamais signalé. Rien ne semble être renvoyé par les services Web et le WaitAll expire juste après dix secondes. Tout fonctionne bien sans le threading jiggerypokery donc ce n'est pas un problème de service web. Qu'est-ce que je fais mal?Quel est le problème avec mon code AutoResetEvent?

AutoResetEvent[] autoEvents; 
    ObservableCollection<Tx3.ResourceService.ResourceTime> resourceTime; 
    ObservableCollection<Tx3.ResourceService.ResourceTimeDetail> resourceTimeDetail; 

    private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     autoEvents = new AutoResetEvent[] 
     { 
      new AutoResetEvent(false), 
      new AutoResetEvent(false), 
     }; 

     var resourceService = getResourceServiceClient(); 

     // Get ResourceTime data for this user 
     resourceService.ListResourceTimeAsync(CategoryWorkItemId, ResourceId); 
     resourceService.ListResourceTimeCompleted += new EventHandler<Tx3.ResourceService.ListResourceTimeCompletedEventArgs>(resourceService_ListResourceTimeCompleted); 

     // Get ResourceTimeDetails 
     resourceService.ListResourceTimeDetailAsync(CategoryWorkItemId, ResourceId); 
     resourceService.ListResourceTimeDetailCompleted += new EventHandler<ListResourceTimeDetailCompletedEventArgs>(resourceService_ListResourceTimeDetailCompleted); 

     WaitHandle.WaitAll(autoEvents, 10000); 

     System.Diagnostics.Debug.WriteLine("do something with both datasets"); 
    } 

    void resourceService_ListResourceTimeCompleted(object sender, Tx3.ResourceService.ListResourceTimeCompletedEventArgs e) 
    { 
     resourceTime = e.Result; 
     autoEvents[0].Set(); 
    } 

    void resourceService_ListResourceTimeDetailCompleted(object sender, ListResourceTimeDetailCompletedEventArgs e) 
    { 
     resourceTimeDetail = e.Result; 
     autoEvents[1].Set(); 
    } 

Répondre

2

Je peux offrir une première estimation naïve: on dirait que vous ajoutez les gestionnaires d'événements après avoir appelé les méthodes qui commencent les opérations asynchrones; il est possible qu'il y ait une condition de concurrence ou un autre problème. Pourriez-vous changer l'ordre des opérations afin de joindre le gestionnaire d'événements, puis commencer l'opération?

+0

Quelle saucisse stupide (!) Supposons que j'ai écrit les gestionnaires le bon chemin. – Paul

+0

Ok, j'ai essayé de corriger les gestionnaires ... même problème. – Paul

+0

S'il s'agit d'un service Web, vous devriez être capable de manipuler Wireshark et de vérifier s'il fonctionne correctement; pouvez-vous vérifier que les réponses reviennent? Si c'est le cas, essayez de définir des points d'arrêt dans les méthodes de rappel et voyez si vous y arrivez. Fondamentalement, juste essayer de vérifier chaque étape le long du chemin que vous pouvez jusqu'à ce que vous voyez où il s'effondre. – qid

1

Ce sont des objets AutoResetEvent - on dirait que vous voulez un ManualResetEvent - la version automatique déclenche tout ce qui attend, mais se réinitialise immédiatement. Les commandes manuelles restent déclenchées, donc si le rappel se produit avant que vous n'ayez le WaitAll, il passera tout de suite immédiatement. En outre, qid est correct - vous attachez vos gestionnaires d'événements trop tard ... donc deux bogues différents se produisent ici.

+0

Je pensais que cela pourrait être le cas aussi - mais selon les doc MSDN l'événement est réinitialisé seulement après qu'il signale un fil. – Aaron

+0

Oh, vous avez raison - idiot moi. qid a probablement la réponse, puis – Clyde

+0

Ok, j'ai essayé de corriger les gestionnaires ... même problème. – Paul

1

Utilisez-vous ce code sur un thread marqué avec l'attribut STA, par exemple le thread d'interface utilisateur principal? Si c'est le cas, la méthode WaitAll n'est pas prise en charge sur ces threads.

Vérifiez here.