private static void TransferAMessageToAServerWorkerThread(MessageToDistributer p_message_to_transfer, int p_thread_id, object p_all_workers_data_lock
                                                           , Dictionary <int, KeyValuePair <Thread, ServerWorkerData> > p_all_workers_data, object p_all_mini_threads_lock, Dictionary <int, Thread> p_all_mini_threads
                                                           , int p_mini_thread_id)
 {
     lock (p_all_workers_data_lock)
     {
         if (p_all_workers_data.ContainsKey(p_thread_id))
         {
             lock (p_all_workers_data[p_thread_id].Value.worker_pulse_object)
             {
                 p_all_workers_data[p_thread_id].Value.send_to_worker_construct.send_to_worker_quque.Enqueue(p_message_to_transfer.Get_message_to_server_worker);
                 p_all_workers_data[p_thread_id].Value.send_to_worker_construct.send_to_worker_queue_flag = true;
                 Monitor.Pulse(p_all_workers_data[p_thread_id].Value.worker_pulse_object);
             }
         }
     }
     lock (p_all_mini_threads_lock)
     {
         if (p_all_mini_threads.ContainsKey(p_mini_thread_id))
         {
             p_all_mini_threads.Remove(p_mini_thread_id);
         }
     }
     Thread.CurrentThread.Abort();
     return;
 }
        public static void DistributerThread(SendToDistributerConstruct p_send_to_disributer_construct, object p_distributer_pulse_object
                                             , Dictionary <int, KeyValuePair <Thread, ServerWorkerData> > p_all_workers_data, object p_all_workers_data_lock)
        {
            Dictionary <int, Thread> all_mini_threads = new Dictionary <int, Thread>();
            object all_mini_threads_lock = new object();

            while (true)
            {
                lock (p_distributer_pulse_object)
                {
                    if (!p_send_to_disributer_construct.send_to_distribuer_queue_flag)
                    {
                        Monitor.Wait(p_distributer_pulse_object);
                    }

                    if (p_send_to_disributer_construct.send_to_distribuer_queue_flag)
                    {
                        if (p_send_to_disributer_construct.send_to_distributer_queue.Count > 0)
                        {
                            MessageToDistributer object_to_do = p_send_to_disributer_construct.send_to_distributer_queue.Dequeue();
                            if (object_to_do.Get_type_of_message_to_distributer == TypeOfMessageToDistributer.CancelAServerWorkerRequest)
                            {
                                int thread_id_to_cancel = object_to_do.Get_thread_id;
                                int mini_thread_id      = HelperFunctions.GetGUID();

                                Thread cancelling_thread = new Thread(() => CancelAServerWorkerThread(p_all_workers_data, p_all_workers_data_lock, thread_id_to_cancel
                                                                                                      , all_mini_threads_lock, all_mini_threads, mini_thread_id));

                                lock (all_mini_threads_lock)
                                {
                                    all_mini_threads.Add(mini_thread_id, cancelling_thread);
                                }
                                cancelling_thread.Start();
                            }

                            else if (object_to_do.Get_type_of_message_to_distributer == TypeOfMessageToDistributer.MessageToServerWorker)
                            {
                                int thread_id_to_get_message = object_to_do.Get_thread_id;
                                int mini_thread_id           = HelperFunctions.GetGUID();

                                Thread transport_thread = new Thread(() => TransferAMessageToAServerWorkerThread(object_to_do, thread_id_to_get_message, p_all_workers_data_lock,
                                                                                                                 p_all_workers_data, all_mini_threads_lock, all_mini_threads, mini_thread_id));

                                lock (all_mini_threads_lock)
                                {
                                    all_mini_threads.Add(mini_thread_id, transport_thread);
                                }
                                transport_thread.Start();
                            }
                        }
                        else
                        {
                            p_send_to_disributer_construct.send_to_distribuer_queue_flag = false;
                        }
                    }
                }
            }
        }
        public void UnAuthsend(int p_thread_id, DialogMessageForClient p_message)
        {
            if (!is_there_unauth_worker_thread(p_thread_id))
            {
                return;
            }
            FinalMessageForClient message_for_user   = new FinalMessageForClient(TypeOfMessage.Dialog, p_message);
            MessageToDistributer  distributer_object = new MessageToDistributer(p_thread_id, new MessageToServerWorker(TypeOfMessageToServerWorker.FinalMessageToClient, message_for_user), TypeOfMessageToDistributer.MessageToServerWorker);

            lock (distributer_pulse_object)
            {
                send_to_distributer_construct.send_to_distributer_queue.Enqueue(distributer_object);
                send_to_distributer_construct.send_to_distribuer_queue_flag = true;
                Monitor.Pulse(distributer_pulse_object);
            }
        }
        public void AuthSend(string p_user_name, ChatMessageForClient p_message)
        {
            int thread_id = get_online_user_thread_id(p_user_name);

            if (thread_id == 0)
            {
                return;
            }
            FinalMessageForClient message_for_user   = new FinalMessageForClient(TypeOfMessage.Chat, p_message);
            MessageToDistributer  distributer_object = new MessageToDistributer(thread_id, new MessageToServerWorker(TypeOfMessageToServerWorker.FinalMessageToClient
                                                                                                                     , message_for_user), TypeOfMessageToDistributer.MessageToServerWorker);

            lock (distributer_pulse_object)
            {
                send_to_distributer_construct.send_to_distributer_queue.Enqueue(distributer_object);
                send_to_distributer_construct.send_to_distribuer_queue_flag = true;
                Monitor.Pulse(distributer_pulse_object);
            }
        }