private static void ResendThread(SendThreadResendConstruct p_resend_construct, object p_send_thread_pulse_object)
 {
     lock (p_send_thread_pulse_object)
     {
         p_resend_construct.resend_flag = true;
         Monitor.Pulse(p_send_thread_pulse_object);
     }
 }
        private static void send_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e, SendThreadResendConstruct p_resend_construct, object p_send_thread_pulse_object)
        {
            Thread resend_thread = new Thread(() => ResendThread(p_resend_construct, p_send_thread_pulse_object));

            resend_thread.Start();
        }
        private static void SendThread(Queue <KeyValuePair <TypeOfSend, byte[]> > p_send_thread_queue, ref bool p_send_thread_queue_flag
                                       , ref bool p_send_thread_cancel_flag, ref bool p_receipt_received_flag, object p_send_thread_pulse_object
                                       , object p_worker_pulse_object, WorkerReceiveThreadConstruct p_recieve_thread_construct, Socket p_client_socket
                                       , ClientWorkerTimer p_worker_timer)
        {
            SendWorkerThreadStatus status = SendWorkerThreadStatus.Normal;

            System.Timers.Timer send_timer = new System.Timers.Timer();
            send_timer.Interval  = 3000;
            send_timer.AutoReset = false;

            Dictionary <int, Thread> all_mini_threads = new Dictionary <int, Thread>();
            object all_mini_threads_lock = new object();

            bool cancelled    = false;
            int  retry_counts = 0;

            byte[] last_message_sent = new byte[1];

            SendThreadResendConstruct resend_construct = new SendThreadResendConstruct();

            send_timer.Elapsed += new System.Timers.ElapsedEventHandler((sender, e) => send_timer_Elapsed(sender, e, resend_construct, p_send_thread_pulse_object));

            while (true)
            {
                lock (p_send_thread_pulse_object)
                {
                    if (!p_send_thread_cancel_flag && !p_receipt_received_flag && !p_send_thread_queue_flag && !resend_construct.resend_flag)
                    {
                        Monitor.Wait(p_send_thread_pulse_object);
                    }
                    if (p_send_thread_cancel_flag)
                    {
                        status = SendWorkerThreadStatus.End;
                        send_timer.Stop();
                        cancelled = true;
                        break;
                    }
                    if (p_receipt_received_flag && status == SendWorkerThreadStatus.WaitingForAReceipt)
                    {
                        send_timer.Stop();
                        retry_counts            = 0;
                        status                  = SendWorkerThreadStatus.Normal;
                        p_receipt_received_flag = false;
                    }
                    if (resend_construct.resend_flag == true && status == SendWorkerThreadStatus.WaitingForAReceipt)
                    {
                        retry_counts++;
                        resend_construct.resend_flag = false;

                        if (retry_counts < 4)
                        {
                            send_timer.Stop();
                            send_timer.Start();

                            int sent_data_length = SendData(p_client_socket, last_message_sent);
                            if (sent_data_length > 0)
                            {
                                p_worker_timer.StartAndReset();
                            }
                        }
                        else
                        {
                            send_timer.Stop();
                            int mini_thread_id = HelperFunctions.GetGUID();
                            p_worker_timer.StartAndReset();
                            status = SendWorkerThreadStatus.Suspended;
                            Thread send_cancel_bytes_to_worker_thead = new Thread(() => SendCancelBytesToWorker(p_worker_pulse_object, p_recieve_thread_construct
                                                                                                                , all_mini_threads, all_mini_threads_lock, mini_thread_id));
                            lock (all_mini_threads_lock)
                            {
                                all_mini_threads.Add(mini_thread_id, send_cancel_bytes_to_worker_thead);
                            }
                            send_cancel_bytes_to_worker_thead.Start();
                        }
                    }
                    if (p_send_thread_queue_flag && (status == SendWorkerThreadStatus.Normal || status == SendWorkerThreadStatus.WaitingForAReceipt))
                    {
                        if (p_send_thread_queue.Count > 0)
                        {
                            if ((p_send_thread_queue.ElementAt(0).Key == TypeOfSend.WithReceipt && status == SendWorkerThreadStatus.Normal) ||
                                (p_send_thread_queue.ElementAt(0).Key == TypeOfSend.WithoutReceipt && (status == SendWorkerThreadStatus.Normal ||
                                                                                                       status == SendWorkerThreadStatus.WaitingForAReceipt)))
                            {
                                KeyValuePair <TypeOfSend, byte[]> send_object = p_send_thread_queue.Dequeue();
                                if (p_send_thread_queue.Count == 0)
                                {
                                    p_send_thread_queue_flag = false;
                                }

                                if (send_object.Key == TypeOfSend.WithReceipt && status == SendWorkerThreadStatus.Normal)
                                {
                                    status            = SendWorkerThreadStatus.WaitingForAReceipt;
                                    last_message_sent = send_object.Value;
                                    int sent_data_length = SendData(p_client_socket, send_object.Value);
                                    if (sent_data_length > 0)
                                    {
                                        p_worker_timer.StartAndReset();
                                    }
                                    send_timer.Start();
                                }
                                else if (send_object.Key == TypeOfSend.WithoutReceipt)
                                {
                                    SendData(p_client_socket, send_object.Value);
                                    p_worker_timer.StartAndReset();
                                }
                            }
                        }
                        else
                        {
                            p_send_thread_queue_flag = false;
                        }
                    }
                }
            }
            if (cancelled)
            {
                send_timer.Stop();
                Thread.CurrentThread.Abort();
            }
        }