1

我必须使用.net 2.0时代.asmx Web服务,我没有构建并且无法控制。然而,该服务是高度可用的,可以处理这一点。.net Web引用客户端的正确多线程用法

我需要帮助的是客户端,并使用visual studio生成的客户端代理正确地从协调立场。目前我正在使用Web引用,但可以根据需要切换到服务引用。但我对WCF一无所知。

我读得越多,我越迷惑自己。

我的具体问题:

鉴于生产方法的线沿线的一个Visual Studio生成的SOAP客户端代理:

Foo(); 
FooAsync(); 
FooCompleted; 

Bar(); 
BarAsync(); 
BarCompleted; 
  1. 应当/我可以调用foo(),从多个线程,就像在Parallel.ForEach中一样?
  2. 应该/我可以在并行foreach中调用FooAsync()吗?这似乎是多余的,因为我已经在另一个线程?这样做安全吗?
  3. 应该/我可以在一个线程上调用FooAsync(),同时在另一个线程上调用BarAsync()?
  4. 这些生成的soap服务类似乎实现了EAP模式。我是pfx/tpl全新的东西,但我一直在研究任务,以更好地管理其中的一些内容。我已经看到了如何使用TaskCompletionSource使用Task来封装EAP的示例。这是更好的方法吗?

回答

2
  1. 你可以尽可能多的线程调用Foo()只要你想(你将不得不做出决定,你应该,自己是否有关)。他们运行(就像你所建议的),就好像他们并行运行一样。

  2. 我提供了一个类似于您想要使用下面的任务并行库(TPL)的示例。为FooAsync()产生一个线程是多余的,如果你已经为Foo()产生了一个线程,但这取决于你正在做什么或想做什么。通常,您可以从UI线程调用Foo(),这反过来会在单独的线程上启动FooAsync()

    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()); 
    } 
    

为一个伟大的介绍TPL及其用途见本link。此外,有关泛型线程的更多信息(以及一些不同的伪装),请参阅J. Albahari's Threading Page

3这完全是主观的,取决于你想做什么。就像回答1所建议的那样,您可以根据需要在任意多个线程上调用这些方法中的每一个。

4 EAP模式see here的一个很好的例子。正如你将会看到的,它基本上就是我上面提供的。对于上述方法,我假设您想在完成FooAsync()BarAsync()之后运行'FooCompleted()and 'BarCompleted()。在这种情况下,我会说EPL模式正是你想要的。

我希望这会有所帮助。