private ulong RegisterComponent(Register _registerMessage, ComponentObject _state)
        {
            ulong newComponentId = 0;

            switch (_registerMessage.Type)
            {
            case RegisterType.ComputationalNode:
                ComputationalNode computationalNode = new ComputationalNode()
                {
                    lastStatus       = DateTime.Now,
                    statusThreads    = new StatusThread[_registerMessage.ParallelThreads],
                    solvableProblems = _registerMessage.SolvableProblems,
                    state            = _state
                };
                // for (int i = 0; i < computationalNode.statusThreads.Length; i++)
                // {
                computationalNode.statusThreads[0] = new StatusThread()
                {
                    TaskIdSpecified            = false,
                    ProblemInstanceIdSpecified = false, ProblemType = "",
                    State = StatusThreadState.Idle, HowLong = 0
                };
                // }
                m_memoryLock.WaitOne();
                newComponentId = computationalNode.Id = m_componentId++;
                m_nodes.Add(computationalNode);
                m_memoryLock.Release();
                break;

            case RegisterType.TaskManager:
                TaskManager taskManager = new TaskManager()
                {
                    lastStatus       = DateTime.Now,
                    statusThreads    = new StatusThread[_registerMessage.ParallelThreads],
                    solvableProblems = _registerMessage.SolvableProblems,
                    state            = _state
                };
                // for (int i = 0; i < taskManager.statusThreads.Length; i++)
                //  {
                taskManager.statusThreads[0] = new StatusThread()
                {
                    TaskIdSpecified            = false,
                    ProblemInstanceIdSpecified = false, ProblemType = "",
                    State = StatusThreadState.Idle, HowLong = 0
                };
                //}
                m_memoryLock.WaitOne();
                newComponentId = taskManager.Id = m_componentId++;
                m_managers.Add(taskManager);
                m_memoryLock.Release();
                break;
            }
            return(newComponentId);
        }
        private void AcceptConnectionCallback(IAsyncResult _asyncResult)
        {
            _allDone.Set();
            Socket handler = listener.EndAccept(_asyncResult);

            handler.ReceiveTimeout = 100;
            ComponentObject state = new ComponentObject()
            {
                m_socket = handler
            };

            //   state.m_receiveBlock.WaitOne();
            handler.BeginReceive(state.m_buffer, 0, state.m_buffer.Length, 0, new AsyncCallback(ReceiveDataCallback), state);
        }
        private bool SendProblemToTaskManager(ulong _problemId)
        {
            ComponentObject state       = new ComponentObject();
            ulong           freeThreads = 0;
            //  bool flag = false;
            Problem problem = m_problems.Find(e => e.Id == _problemId);

            /* foreach (var computationalNode in m_nodes)
             *   if (computationalNode.solvableProblems.Contains(problem.ProblemType))
             *       foreach (var thread in computationalNode.statusThreads)
             *           if (thread.State == StatusThreadState.Idle)
             *               freeThreads++;*/
            freeThreads = (ulong)m_nodes.Count(node => node.solvableProblems.Contains(problem.ProblemType) && node.statusThreads[0].State == StatusThreadState.Idle);

            foreach (var taskManager in m_managers)
            {
                if (taskManager.solvableProblems.Contains(problem.ProblemType) && taskManager.statusThreads[0].State == StatusThreadState.Idle)
                {
                    problem.manager = taskManager;
                    state           = taskManager.state;
                    break;
                }
            }
            if (state.m_socket == null || freeThreads == 0)
            {
                problem.manager = null;
                return(false);
            }
            DivideProblem divideProblem = new DivideProblem()
            {
                ComputationalNodes = freeThreads,
                Data        = problem.Data,
                Id          = _problemId,
                ProblemType = problem.ProblemType
            };

            return(Send(SerializeMessage(divideProblem), state.m_socket));
        }
        private void ReceiveDataCallback(IAsyncResult _asyncResult)
        {
            int             bytesRead = 0;
            ComponentObject state     = (ComponentObject)_asyncResult.AsyncState;
            Socket          handler   = state.m_socket;

            try
            {
                bytesRead = handler.EndReceive(_asyncResult);
            }
            catch (SocketException)
            {
                //  state.m_receiveBlock.Release();
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
                return;
            }
            if (bytesRead > 0)
            {
                do
                {
                    state.m_offset += bytesRead;
                    if (state.m_offset == state.m_buffer.Length)
                    {
                        byte[] request = new byte[state.m_buffer.Length * 2];
                        state.m_buffer.CopyTo(request, 0);
                        state.m_buffer = request;
                    }
                    try
                    {
                        bytesRead = handler.Receive(state.m_buffer, state.m_offset, state.m_buffer.Length - state.m_offset, 0);
                    }
                    catch (SocketException) { bytesRead = 0; }
                } while (bytesRead > 0);
            }
            if (state.m_offset > 0)
            {
                List <byte[]> messages = DivideMessages(state.m_buffer, state.m_offset);
                //state.m_receiveBlock.Release();
                byte[] msg = new byte[0];
                for (int i = 0; i < messages.Count; i++)
                {
                    msg = msg.Concat(messages[i]).ToArray();
                    switch (GetMessageType(msg))
                    {
                    case "Status":
                        try
                        {
                            var statusMessage = DeserializeMessage <Status>(msg);
                            RefreshLastStatus(statusMessage);
                            Console.WriteLine("Status message received from component ID = {0}", statusMessage.Id);
                            msg = new byte[0];
                        }
                        catch (Exception) { continue; }
                        break;

                    case "Register":
                        try
                        {
                            var registerMessage = DeserializeMessage <Register>(msg);
                            Console.WriteLine("Register Message received from {0}, address: {1}",
                                              registerMessage.Type == RegisterType.ComputationalNode ? "ComputationalNode" : "TaskManager",
                                              handler.RemoteEndPoint.ToString());
                            ulong componentId = RegisterComponent(registerMessage, state);
                            ResponseRegisterMessage(handler, componentId);
                            msg = new byte[0];
                        }
                        catch (Exception) { continue; }
                        break;

                    case "SolveRequest":
                        try
                        {
                            var   solveRequestMessage = DeserializeMessage <SolveRequest>(msg);
                            ulong problemId           = AddProblem(solveRequestMessage);
                            Console.WriteLine("Problem nr {0} was registered", problemId);
                            ResponseSolveRequest(state.m_socket, problemId);
                            m_memoryLock.WaitOne();
                            SendProblemToTaskManager(problemId);
                            m_memoryLock.Release();
                            msg = new byte[0];
                        }
                        catch (Exception) { continue; }
                        break;

                    case "SolutionRequest":
                        try
                        {
                            var solutionRequestMessage = DeserializeMessage <SolutionRequest>(msg);
                            SendSolutionInfo(handler, solutionRequestMessage);
                            msg = new byte[0];
                        }
                        catch (Exception) { continue; }
                        break;

                    case "SolvePartialProblems":
                        try
                        {
                            var solvePartialProblemMessage = DeserializeMessage <SolvePartialProblems>(msg);
                            SaveTaskManagerDataAndSendPartialProblemsToNodes(solvePartialProblemMessage);
                            Console.WriteLine("Sent partial problem to nodes. Problem ID={0}", solvePartialProblemMessage.Id);
                            msg = new byte[0];
                        }
                        catch (Exception) { continue; }
                        break;

                    case "Solutions":
                        try
                        {
                            var solutionsMessage = DeserializeMessage <Solutions>(msg);
                            ReceiveSolution(solutionsMessage);
                            Console.WriteLine("Solution Id = {0} received from component", solutionsMessage.Id);
                        }
                        catch (Exception) { continue; }
                        break;

                    default:
                        Console.WriteLine("Unknown message type ");
                        break;
                    }
                }
                state.m_offset = 0;
                try
                {
                    // state.m_receiveBlock.WaitOne();
                    handler.BeginReceive(state.m_buffer, 0, state.m_buffer.Length, 0, new AsyncCallback(ReceiveDataCallback), state);
                }
                catch (Exception) { }
            }
        }