1

我必须使用我没有构建且无法控制的 .net 2.0 时代的 .asmx 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 将 EAP 与 Task 包装的示例。这是更好的方法吗?
4

1 回答 1

2
  1. 您可以根据需要调用任意Foo()数量的线程(您必须自己决定是否应该)。它们运行(就像您建议的那样)就好像它们并行运行一样。

  2. 我已经提供了一个示例,例如您想要使用下面的任务并行库(TPL)FooAsync()如果您已经为其生成了一个线程,那么生成一个线程是多余的,Foo()但这取决于您正在做什么或想要做什么。通常,您会Foo()从 UI 线程调用,而后者又会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 及其使用的精彩介绍,请参阅此链接。此外,有关通用线程(以及一些不同的伪装)的更多信息,请参阅J. Albahari 的线程页面

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

4 有关 EAP 模式的一个很好的示例,请参见此处。正如您将看到的,它基本上就是我上面提供的内容。对于上述方法,我假设您想在完成and 'BarCompleted()后运行 'FooCompleted() 。在这种情况下,我会说 EPL 模式正是您想要的。FooAsync()BarAsync()

我希望这有帮助。

于 2012-04-25T07:39:19.950 回答