0

In my web socket wcf service I'm using timer elapsed event to do some logic on my object and after that send information to client (by callback object). I also track callback closed event to clean all object that I'm using in timer elapsed event handler. The problem that i occured is that, when I'm trying to dispose my object i get errors that is still working and to prevent that i try to use lock in both code (timer elapsed event and closed channel event) but it not working correctly (i'm still getting errors that i'm calling method on my object that is no allowed for this moment - this mean that timer elapsed and also call it in the same time).

Is WCF do something special which causes to lock don't work as I expected ?

Here is some of my code:

[ServiceContract(CallbackContract = typeof(IWebSocketsCallback))]
public interface IWebSockets
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void Start(Message msg);
}

  [ServiceContract]
public interface IWebSocketsCallback
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void SendToClient(Message msg);
}

    public class WebSockets : IWebSockets
{
    private IWebSocketsCallback callback;
    private bool handlePIChanges = false;
    private PIDataPipe pipe;
    private PIEventsProducer piEventsProducer;
    private Timer timer;
    private readonly object timerLock = new object();
    private readonly object pipeLock = new object();
    private bool isPipeClosed = false;

    public WebSockets()
    {
        callback = OperationContext.Current.GetCallbackChannel<IWebSocketsCallback>();
        ((IChannel)callback).Closed += WebSockets_Closed;
    }

    public void Start(Message msg)
    {
        // some custom logic that i ommited ...

        timer = CreateTimer();
        timer.Elapsed += (sender, e) => PIQueryingCallback(pipe, timer);
    }

    private void WebSockets_Closed(object sender, EventArgs e)
    {
        lock (timerLock)
        {
            handlePIChanges = false;

            if (timer != null)
            {
                timer.Stop();
                timer.Dispose();
                piEventsProducer.Clear();
            }
        }

        lock (pipeLock)
        {
            if (pipe != null)
            {
        pipe.RemoveSignups(pipe.AsReadOnly()); // this cause error, because GetObserverEvents not stopped working   
                pipe.Close();
                isPipeClosed = true;
            }
        }
    }

    private void PIQueryingCallback(PIDataPipe pipe, Timer myTimer)
    {
        bool moreIndicator;
        AFErrors<PIPoint> errors;

        lock (pipeLock)
        {
            do
            {
                if (handlePIChanges && !isPipeClosed)
                {
                    try
                    {
                        errors = pipe.GetObserverEvents(2000, out moreIndicator); // this method calls make block for other call on this object untill it return results
                    }
                    catch (Exception e)
                    {
                        moreIndicator = false;
                        continue;
                    }
                }
                else
                {
                    moreIndicator = false;
                }
            }
            while (moreIndicator);
        }

        if (handlePIChanges)
        {
            lock (timerLock)
            {
                if (handlePIChanges)
                {
                    myTimer.Start();
                }
            }
        }
    }

// this method is called after GetObserveEventsCompleted
    private void HandlePIDataEventProducerChanges(string msg)
    {
        if (handlePIChanges && !isPipeClosed)
        {
            if (((IChannel)callback).State == CommunicationState.Opened)
            {
                try
                {
                    callback?.SendPIDataChangesToClient(CreateMessage(msg));
                }
                catch (Exception ex)
                {

                }
            }
        }
    }


}
dawid
  • 11
  • 2
  • What is the specific error message? – Theobald Du Jun 17 '21 at 06:24
  • My pipe object have logic: Whenever GetObserverEvents is called, set flags that not allowed to do anything other untill this method complete operation. So when callback closed event had triggered I'm getting error from pipe object - observer event in progress so I want to avoid situation where I calling method when GetObserveEvents not completed execution. – dawid Jun 17 '21 at 07:43
  • You can take a look at: https://stackoverflow.com/questions/61186625/how-to-block-code-flow-until-an-event-is-fired-in-c-sharp – Theobald Du Jul 16 '21 at 02:15

0 Answers0