1

I have a service that receives requests and processes them gradually (using ActionBlock).

Sometimes I need to wait until it's processed. I have the option to enter a callback. Is there a way to pause the run until a callback is called?

Something like this, but better:

    bool complete = true;
    service.AddRequest(new ServiceRequest()
    {
        OnComplete = (req) =>
        {
            complete = true;
        }
    });
    while (!complete) Thread.Sleep(100);

Longer code for context:

public class Service
{
    protected ActionBlock<ServiceRequest> Requests;
    public Service()
    {
        Requests = new ActionBlock<ServiceRequest>(req => {
            // do noting
            Thread.Sleep(1000);
            req.OnComplete?.Invoke(req);
        });
    }

    public void AddRequest(ServiceRequest serviceRequest) => Requests.Post(serviceRequest);
}

public class ServiceRequest
{
    public Action<ServiceRequest> OnComplete;
    string Foo;
}

public class App
{
    public static void Start()
    {
        var service = new Service();
        service.AddRequest(new ServiceRequest());
        // I need to wait for processing

        // smelly code!!
        bool complete = true;
        service.AddRequest(new ServiceRequest()
        {
            OnComplete = (req) =>
            {
                complete = true;
            }
        });
        while (!complete) Thread.Sleep(100);
        // smelly code!! end
    }
}
VillageTech
  • 1,968
  • 8
  • 18
Murdej Ukrutný
  • 329
  • 1
  • 4
  • 10
  • 1
    Does this answer your question? [What is the difference between ManualResetEvent and AutoResetEvent in .NET?](https://stackoverflow.com/questions/153877/what-is-the-difference-between-manualresetevent-and-autoresetevent-in-net) – Thomas Weller Dec 17 '19 at 13:30

1 Answers1

2

There is mistake in your code, the initial value of complete should be false ;)

bool complete = false; // initial value
service.AddRequest(new ServiceRequest()
{
    OnComplete = (req) =>
    {
        complete = true;
    }
});
while (!complete) Thread.Sleep(100);

To prevent active waiting in loop you can use the AutoResetEvent:

AutoResetEvent completedEv = new AutoResetEvent();
service.AddRequest(new ServiceRequest()
{
    OnComplete = (req) =>
    {
        completedEv.Set();
    }
});

completedEv.WaitOne();

NOTE: the AutoResetEvent implements IDisposable interface, so you have to be sure that it will be disposed even in error situations.

VillageTech
  • 1,968
  • 8
  • 18