【问题标题】:Polling a WCF service method in a blocking call within a another WCF service在另一个 WCF 服务内的阻塞调用中轮询 WCF 服务方法
【发布时间】:2018-04-11 00:40:34
【问题描述】:

更新:

问题已解决。这两段代码实际上都有效。一个潜在的问题导致失败。


我不是线程专家,但这是我的场景。

我有两个 WCF 服务(ServiceAServiceB

ServiceA必须

  1. 每秒或配置的间隔轮询ServiceB
  2. 对于某种状态,
  3. 阻塞直到ServiceB 恢复所需状态
  4. ServiceA 方法然后进行下一个操作

专注于Service A的实现以实现需求,并假设我使用Service B的生成服务引用,干净地处理和关闭,定义接口:

public class ServiceA : IServiceA
{
   public ResultObject ServiceAMethod()
   {
       var serviceBClient = new ServiceBReference.ServiceBClient();
       //do sometthing
       //call ServiceB every 1second until the status changes or a WCF timeout ends the process
       return new ResultObject{/*set whatever properties need to be set*/}
    }
}

我已经尝试过并且没有阻止:

尝试 1

public class ServiceA : IServiceA
{
   public ResultObject ServiceAMethod()
   {
        var serviceBClient = new ServiceBReference.ServiceBClient();
        //do sometthing
        //call ServiceB every 1second until the status changes or a WCF timeout ends the process

        var cancellationTokenSource = new CancellationTokenSource();
        var token = cancellationTokenSource.Token;

        SomeStatusEnum status;
        int pollingInterval = 1000;
        var listener = Task.Factory.StartNew(() =>
        {
            status = serviceBClient.GetStatus();
            while (status != SomeStatusEnum.Approved)
            {
                Thread.Sleep(pollingInterval);
                if (token.IsCancellationRequested)
                    break;

                status = serviceBClient.GetStatus();
            }
        }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
       return new ResultObject{/*set whatever properties need to be set determined by status*/}
    }
}
}

尝试 2

public class ServiceA : IServiceA
{
   public ResultObject ServiceAMethod()
   {
        var serviceBClient = new ServiceBReference.ServiceBClient();
        //do sometthing
        //call ServiceB every 1second until the status changes or a WCF timeout ends the process

        SomeStatusEnum status;
        int pollingInterval = 1000;

        status = serviceBClient.GetStatus();
        while (status == SomeStatusEnum.Approved)
        {
            status = serviceBClient.GetStatus();;
            if (status != SomeStatusEnum.Approved)
            {
                break;
            }
            Thread.Sleep(pollingInterval);
        }
       return new ResultObject{/*set whatever properties need to be set determined by status*/}
    }
}

在这两种情况下,状态都不会设置为预期值。我可能做错了什么?是否存在与 WCF 应用程序相关的可能导致此问题的行为?

我的来源

  1. Should I always use Task.Delay instead of Thread.Sleep?
  2. WCF Thread Sleep
  3. C# error System.NullReferenceException
  4. Calling a method every x minutes
  5. When to use Task.Delay, when to use Thread.Sleep?

【问题讨论】:

  • 为什么对 ServiceB 的调用不能是阻塞(同步)调用。无论如何,您需要让 ServiceA 等到结果出现。是 ServiceB PerInstance、PerCall 还是 Singleton - 在 ServiceB 方法调用中放置一些日志以查看返回的状态。
  • 如果它是同步的,@PrateekShrivastava 怎么做?
  • 对 ServiceB 的调用是同步的。 GetStatus() 将被阻止,直到返回正确的状态。所以实际上 ServiceA 正在等待来自 ServiceB 的响应。
  • 问题已解决。这两段代码实际上都有效。

标签: c# wcf task blocking


【解决方案1】:

这两段代码实际上都可以工作。

可以删除问题,但选择保留它以供参考,因为它还包括可能对下一个人有帮助的参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 2014-12-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2015-04-08
    相关资源
    最近更新 更多