/// <summary> /// This helper method sends out all the strings in the queue by calling /// the BytesSent callback again and again. It tries to send the string at the /// front of queue. It contains a call to another helper method BytesSent /// to ensure all the bytes from the front string are sent before calling this /// method again to send the next string. /// /// IMPLEMENTATION NOTE: Should be called from within a lock for thread-safety. /// </summary> private void HandleSendQueue() { while (sendQueue.Count > 0) { sendBytes = encoding.GetBytes(sendQueue.First <SendRequest>().Text); try { socket.BeginSend(sendBytes, sendCount = 0, sendBytes.Length, SocketFlags.None, new AsyncCallback(BytesSent), (object)null); break; } catch (Exception ex) { SendRequest request = sendQueue.Dequeue(); ThreadPool.QueueUserWorkItem((WaitCallback)(x => request.SendBack(ex, request.Payload))); } } }
/// <summary> /// The callback method used when sending bytes. It makes sure that all of the bytes /// are sent before making the approriate callback and call to HandleSendQueue. /// /// IMPLEMENTATION NOTE: Should be called from within a lock for thread-safety. /// </summary> /// <param name="arg">Object containing status of asyn operation</param> private void BytesSent(IAsyncResult arg) { try { sendCount = sendCount + socket.EndSend(arg); } catch (Exception ex) { SendRequest request = sendQueue.Dequeue(); ThreadPool.QueueUserWorkItem((WaitCallback)(x => request.SendBack(ex, request.Payload))); HandleSendQueue(); return; } if (sendCount == sendBytes.Length) { lock (sendQueue) { SendRequest req = sendQueue.Dequeue(); ThreadPool.QueueUserWorkItem((WaitCallback)(x => req.SendBack((Exception)null, req.Payload))); HandleSendQueue(); } } else { try { socket.BeginSend(sendBytes, sendCount, sendBytes.Length - sendCount, SocketFlags.None, new AsyncCallback(BytesSent), (object)null); } catch (Exception ex) { SendRequest request = sendQueue.Dequeue(); ThreadPool.QueueUserWorkItem((WaitCallback)(x => request.SendBack(ex, request.Payload))); HandleSendQueue(); } } }