views:

116

answers:

1
/// <summary></summary>
private Byte[] _ReceiveBytes(Int32 size)
{
    MemoryStream memory = null;  
    SocketAsyncEventArgs args = null;
    EventHandler<SocketAsyncEventArgs> completed = null;
    Exception exception = null;
    Int32 last_update = Environment.TickCount;
    Boolean finished = false;
    Int32 count = 0;
    Int32 received = 0;

    completed = new EventHandler<SocketAsyncEventArgs>((s, e) =>
    {
     try
     {
      count = e.BytesTransferred;
      last_update = (count > 0 ? Environment.TickCount : last_update);
      memory.Write(e.Buffer, 0, count);
      received += count;
      finished = (received == size);
      if (!finished)
      {
       count = Math.Min(_ChunkSize, size - received);
       args.SetBuffer(new Byte[count], 0, count);
       if (!_Socket.ReceiveAsync(e))
       {
        completed(s, e);
       }
      }
     }
     catch (Exception ex)
     {
      exception = ex;
     }
    });

    using (memory = new MemoryStream())
    using (args = new SocketAsyncEventArgs())
    {
     count = Math.Min(_ChunkSize, size - received);
     args.SetBuffer(new Byte[count], 0, count);
     args.Completed += completed;

     if (!_Socket.ReceiveAsync(args))
     {
      completed(_Socket, args);
     }

     while (!finished)
     {
      Thread.Sleep(_SleepTimeSpan);
      if (exception != null)
      {
       throw new Exception(_ReceiveExceptionMessage, exception);
      }
      else if (!finished && Environment.TickCount - last_update > _ReceiveTimeout)
      {
       throw new TimeoutException(_TimeoutExceptionMessage);
      }
     }

     return memory.ToArray();
    }
}
+2  A: 

There are problems. "finished" needs to be volatile but can't be, use MRE. Your timeout code can crash on a OverflowException. You're translating exceptions.

But the approach makes no sense, there's no point in waiting for an async operation to complete. Use Socket.ReceiveTimeout to get the timeout exception.

Hans Passant
I don't think finished needs to be volatile in this case. http://stackoverflow.com/questions/59422/is-a-bool-read-write-atomic-in-c
ChaosPandion