0

Update:

The issue has been resolved. Both pieces of code actually work. An underlying issue was causing failure.


I am not much of a threading expert but this is my scenario.

I have two WCF services (ServiceA and ServiceB)

ServiceA must

  1. poll ServiceB every second or configured interval,
  2. for a certain status,
  3. blocking until ServiceB retuns the desired status
  4. ServiceA method then proceeds to its next action

Focusing on the implementation of Service Ato achieve the requirement, and assuming I am using a generated service reference for Service B, cleanly disposing and closing, with interfaces defined:

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*/}
    }
}

What I have tried and does not block:

Attempt 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*/}
    }
}
}

Attempt 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*/}
    }
}

In both cases, status is never set to the expected value. What could I be doing wrong? Is there behavior associated with WCF applications that could be causing this?

My sources:

  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?
tinonetic
  • 7,751
  • 11
  • 54
  • 79
  • Why cant the call to ServiceB be a Blocking (Synchronous) call. Anyways you need to make ServiceA wait until result appears. Is ServiceB PerInstance, PerCall or Singleton -- put some logs in ServiceB method call to see what status is being returned. – Prateek Shrivastava Apr 11 '18 at 01:35
  • If its synchronous, how would this be done @PrateekShrivastava? – tinonetic Apr 11 '18 at 05:59
  • When the call to ServiceB is synchronous. GetStatus() would be blocked until the correct status is returned. So in effect ServiceA is waiting for response from ServiceB. – Prateek Shrivastava Apr 11 '18 at 07:37
  • The issue has been resolved. Both pieces of code actually work. – tinonetic Apr 11 '18 at 09:37

1 Answers1

0

Both pieces of code actually work.

Can delete the question, but choosing to leave it for reference purposes, as it also includes references that may assist the next person.

tinonetic
  • 7,751
  • 11
  • 54
  • 79