Home > front end >  .NET client-side WCF with queued requests
.NET client-side WCF with queued requests

Time:08-18

Background

I'm working on updating legacy software library. The legacy code uses an infinitely looping System.Threading.Thread that executes processes in the queue. These processes perform multiple requests with another legacy system that can only process one request at a time.

I'm trying to modernize, but I'm new to WCF services and there may be a big hole in my knowledge that'd simplify things.

WCF Client-Side Host

In modernizing, I'm trying to move to a client-side WCF service. The WCF service allows requests to be queued from multiple a applications. The service takes a request and returns a GUID back so that I can properly associate via the callbacks.

public class SomeService : ISomeService
{
    public Guid AddToQueue(Request request)
    {
    // Code to add the request to a queue, return a Guid, etc.
    }
}

public interface ISomeCallback
{
    void NotifyExecuting(Guid guid)
    void NotifyComplete(Guid guid)
    void NotifyFault(Guid guid, byte[] data)
}

WCF Client Process Queues

The problem I'm having is that the legacy processes can include more than one request. Process 1 might do Request X then Request Y, and based on those results follow up with Request Z. With the legacy system, there might be Processes 1-10 queued up.

I have a cludgy model where the process is executed. I'm handling events on the process to know when it's finished or fails. But, it just feels really cludgy...

public class ActionsQueue
{
    public IList<Action> PendingActions { get; private set; }
    public Action CurrentAction { get; private set; }

    public void Add(Action action)
    {
        PendingAction.Add(action)
        if (CurrentAction is null)
            ExecuteNextAction();
    }

    private void ExecuteNextAction()
    {
        if (PendingActions.Count > 0)
        {
            CurrentAction = PendingActions[0];
            PendingActions.RemoveAt(0);
            CurrentAction.Completed  = OnActionCompleted;
            CurrentAction.Execute();
        }
    }

    private OnActionCompleted(object sender, EventArgs e)
    {
        CurrentAction = default;
        ExecuteNextAction();
    }
}

public class Action
{
    internal void Execute()
    {
    // Instantiate the first request
    // Add handlers to the first request
    // Send it to the service
    }

    internal void OnRequestXComplete()
    {
    // Use the data that's come back from the request
    // Proceed with future requests
    }
}

With the client-side callback the GUID is matched up to the original request, and it raises a related event on the original requests. Again, the implementation here feels really cludgy.

I've seen example of Async methods for the host, having a Task returned, and then using an await on the Task. But, I've also seen recommendations not to do this.

Any recommendations on how to untangle this mess into something more usable are appreciated. Again, it's possible that there's a hole in my knowledge here that's keeping me from a better solutiong.

Thanks

CodePudding user response:

Queued communication between the client and the server of WCF is usually possible using a NetMsmqbinding, which ensures persistent communication between the client and the server. See this article for specific examples.

If you need efficient and fast message processing, use a non-transactional queue and set the ExactlyOnce attribute to False, but this has a security impact. Check this docs for further info.

  • Related