Geoff

Geoff

  • NA
  • 3
  • 0

Async Socket Sync Problem

Jul 27 2006 7:47 PM
I am having a problem keeping my GUI thread and async socket thread from doing the tango.

 I have isolated the problem down to a single line, but without that line the app is useless. So I need to figure out what why the error is occuring.

The problem occurs when the Request(object request, Type expectedResponse) method is called. This method passes an object to the server and then uses an AutoResetEvent.WaitOne(750, false) to wait for the server to reply to the request object through OnDataReceived(IAsyncResult asyncResult). After receiving the data through OnDataReceived(IAsyncResult asyncResult) I convert the object from a byte array back into an object and then raise an event to let the owner of the client class know that data has been received. It is this event that causes the problems.

This error occurs more frequently as the rate of transfers increases. A receipt every 1 second works pretty consistantly, but a receipt every 100ms causes instant death.

Code:
****************************************************************

private object response;
private AutoResetEvent receivedRequestedData;

public object Request(object data, Type responseType)
{
    // Reset the notification service
    receivedRequestedData.Reset();

    this.expectedResponse = responseType;

    // Send the data to the server
    if (Send(data) == 0)
        throw new ApplicationException("Unable to sent the request");

    // Block the thread until a reply is received or the request timesout 5 seconds
    if (!receivedRequestedData.WaitOne(750, false))
        _receiveFailed++;

    this.expectedResponse = null;

    // Return the received object
    return this.response; // Response is set by the OnDataReceived method
}

private void OnDataReceived(IAsyncResult asyncResult)
{
    ...
    object data = Deserialize(objectBuffer);

    if (data.GetType() == this.ExpectedResponseType)
    {
        this.response = data;
        receivedRequestData.Set(); // Threading.AutoResetEvent
    }

    **** This is the line that causes the application to loose sync ****
    **** If I comment out this line the application works flawlessly even @ a receipt every 100ms ****
    TriggerEvent(DataReceived, this, new DataInterchangeEventArgs(data, length));
    ...
}

protected void TriggerEvent(Delegate del, params object[] args)
{
    if (del != null)
    {
        try
        {
            foreach (Delegate d in del.GetInvocationList())
            {
                System.ComponentModel.ISynchronizeInvoke s;
                s = d.Target as System.ComponentModel.ISynchronizeInvoke;

                if (s != null && s.InvokeRequired)
                    s.Invoke(d, args);
                else
                    d.DynamicInvoke(args);
            }
        }
        catch (Exception ex)
        {
            RecordError("TriggerEvent", ex);
        }
    }
}