private async Task SendLoop() { while (!stopping) { byte[] message; lock (SendBuffer) { if (DateTime.Now - LastSend < resendTimeout) { Monitor.Wait(SendBuffer, resendTimeout - (DateTime.Now - LastSend)); continue; } if (failedSendAttempts > 5) { dead = true; return; } int bytesAvailible = SendBuffer.GetAvailibleBytesAtBegin(); if (bytesAvailible <= 0) { Monitor.Wait(SendBuffer); continue; } int toRead = bytesAvailible < SendBy ? bytesAvailible : SendBy; message = new byte[1 + 8 + toRead]; message[0] = (byte)CommandCode.Data; byte[] lengthBuffer = BitConverter.GetBytes(SendBuffer.FirstAvailibleAbsolutePosition); Array.Copy(lengthBuffer, 0, message, 1, lengthBuffer.Length); byte[] buffer = new byte[toRead]; SendBuffer.TryGetFromBegin(buffer, toRead); Monitor.PulseAll(SendBuffer); Array.Copy(buffer, 0, message, 1 + 8, toRead); } Console.WriteLine($"Sending {message.Length} bytes to server"); try { await udpclient.SendAsync(message, message.Length, server); LastSend = DateTime.Now; failedSendAttempts++; } catch (SocketException) { } } }