1

Je dois consommer un service web .asm 2.0 .netx que je n'ai pas construit et que je ne peux pas contrôler. Cependant, le service est hautement disponible et peut gérer cela. Ce dont j'ai besoin d'aide est le client, et l'utilisation du proxy client généré par Visual Studio correctement à partir d'un point de vue de la concurence. Actuellement, j'utilise une référence Web, mais je peux passer à une référence de service si nécessaire. Cependant, je ne connais rien à la WCF.Utilisation correcte multithread du client de référence Web .Net

Plus je lis, plus je me trompe.

Mes questions spécifiques:

Étant donné un studio visuel généré proxy client de savon qui produit des méthodes le long des lignes de:

Foo(); 
FooAsync(); 
FooCompleted; 

Bar(); 
BarAsync(); 
BarCompleted; 
  1. devrait/ce que je peux appeler Foo() de plus d'un fil , comme dans un Parallel.ForEach?
  2. Devrais/dois-je appeler FooAsync() à l'intérieur du foreach parallèle? Cela semble redondant, puisque je suis déjà sur un autre fil? Est-il sûr de le faire?
  3. Devrais/puis-je appeler FooAsync() sur un thread, tout en appelant BarAsync() sur un autre thread?
  4. Ces classes de service de savon générées semblent implémenter le modèle EAP. Je suis tout nouveau dans les trucs pfx/tpl, mais j'ai regardé les tâches comme un moyen de mieux gérer ça. J'ai vu des exemples de comment emballer EAP avec la tâche en utilisant TaskCompletionSource. Est-ce la meilleure approche ici?

Répondre

2
  1. Vous pouvez appeler Foo() sur autant de sujets que vous voulez (vous devrez prendre la décision quant à savoir si vous devrait, vous-même). Ils courent (comme vous le suggérez) comme s'ils couraient en parallèle.

  2. J'ai fourni un exemple de quelque chose comme ce que vous voulez en utilisant la Task Parallel Library (TPL) ci-dessous. Il est redondant de générer un thread pour FooAsync() si vous en avez déjà engendré un pour Foo() mais cela dépend de ce que vous faites ou que vous voulez faire. Généralement, vous appelez Foo() à partir du thread d'interface utilisateur, qui à son tour lance le FooAsync() sur un thread distinct.

    private void Foo() 
    { 
        // Get TaskScheduler to facilitate manipulation of GUI on UI Thread. 
        TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
    
        // Cancellation support. 
        CancellationTokenSource cancelSource = new CancellationTokenSource(); 
        CancellationToken token = cancelSource.Token; 
    
        // Spin-off onto background thread. 
        Task<bool> asyncFooTask = null; 
        asyncFooTask = Task.Factory.StartNew<bool>(() => asyncFoo(uiScheduler, token, _dynamic), token); 
    
        // Continuation/call-back/error-handling. 
        asyncTask.ContinueWith(task => 
        { 
         // Check task status. 
         switch (task.Status) 
         { 
          // Handle any exceptions to prevent UnobservedTaskException.    
          case TaskStatus.RanToCompletion: 
           if (asyncTask.Result) 
            // Success. Do stuff. 
           else 
            // Failed. Do stuff. 
           break; 
          case TaskStatus.Canceled: 
           if (task.Exception != null) 
            // Cancelled with exception. 
           else 
            // User cancelled. 
           break; 
          case TaskStatus.Faulted: 
           if (task.Exception != null) 
            // AggregateException thrown by antecident. 
           else 
            // Task failed... 
           break; 
         } 
         return; 
        }, TaskScheduler.FromCurrentSynchronizationContext()); 
    } 
    

Voir cette link pour une excellente introduction à TPL et son utilisation. En outre, pour plus d'informations sur le threading générique (et sur certains aspects différents), voir J. Albahari's Threading Page.

3 Ceci est totalement subjectif et dépend de ce que vous voulez faire. Comme la réponse 1 le suggère, vous pouvez appeler chacune de ces méthodes sur autant de threads que vous le souhaitez.

4 Pour un bon exemple du modèle EAP see here. Comme vous le verrez, c'est essentiellement ce que j'ai fourni ci-dessus. Pour les méthodes ci-dessus, je suppose que vous voulez exécuter 'FooCompleted() and 'BarCompleted() après FooAsync() et BarAsync() ont terminé. Dans ce cas, je dirais que le modèle EPL est exactement ce que vous voulez.

J'espère que cela aide.