private void _MessageProcessorStart()
 {
     Thread.CurrentThread.Name = "EventMessageProcessor_" + Thread.CurrentThread.ManagedThreadId.ToString();
     while (!_exit)
     {
         if (_mreMessageWaiting.WaitOne(1000))
         {
             lock (_splitMessages)
             {
                 while (_splitMessages.Count > 0)
                 {
                     _processingMessages.Add(_splitMessages[0]);
                     _splitMessages.RemoveAt(0);
                 }
             }
             bool run = true;
             Queue<ASocketMessage> msgs = new Queue<ASocketMessage>();
             while (run)
             {
                 while (_processingMessages.Count > 0)
                 {
                     string origMsg = _processingMessages[0];
                     _processingMessages.RemoveAt(0);
                     Dictionary<string, string> pars = ASocketMessage.ParseProperties(origMsg);
                     string subMsg = "";
                     //fail safe for delayed header
                     if (!pars.ContainsKey("Content-Type"))
                     {
                         if (_disposeInvalidMesssage != null)
                             _disposeInvalidMesssage(origMsg);
                         break;
                     }
                     if (pars.ContainsKey("Content-Length"))
                     {
                         if (int.Parse(pars["Content-Length"]) > 0)
                         {
                             if (_processingMessages.Count > 0)
                             {
                                 subMsg = _processingMessages[0];
                                 _processingMessages.RemoveAt(0);
                             }
                             else
                             {
                                 _processingMessages.Insert(0, origMsg);
                                 break;
                             }
                         }
                     }
                     switch (pars["Content-Type"])
                     {
                         case "text/event-plain":
                             if (subMsg == "")
                             {
                                 _processingMessages.Insert(0, origMsg);
                                 break;
                             }
                             else
                             {
                                 SocketEvent se;
                                 se = new SocketEvent(subMsg);
                                 if (se["Content-Length"] != null)
                                 {
                                     if (_processingMessages.Count > 0)
                                     {
                                         se.Message = _processingMessages[0];
                                         _processingMessages.RemoveAt(0);
                                     }
                                     else
                                     {
                                         _processingMessages.Insert(0, origMsg);
                                         _processingMessages.Insert(1, subMsg);
                                         break;
                                     }
                                 }
                                 if (se.EventName == "BACKGROUND_JOB")
                                 {
                                     lock (_commandThreads)
                                     {
                                         if (_commandThreads.ContainsKey(se["Job-UUID"]))
                                         {
                                             lock (_awaitingCommandReturns)
                                             {
                                                 _awaitingCommandReturns.Add(se["Job-UUID"], se.Message.Trim('\n'));
                                             }
                                             ManualResetEvent mre = _commandThreads[se["Job-UUID"]];
                                             _commandThreads.Remove(se["Job-UUID"]);
                                             mre.Set();
                                         }
                                     }
                                 }
                                 msgs.Enqueue(se);
                             }
                             break;
                         case "command/reply":
                             CommandReplyMessage crm = new CommandReplyMessage(origMsg, subMsg);
                             msgs.Enqueue(crm);
                             if (crm["Job-UUID"] != null)
                             {
                                 lock (_awaitingCommandsEvents)
                                 {
                                     _currentCommandID = crm["Job-UUID"];
                                     _awaitingCommandsEvents.Dequeue().Set();
                                 }
                             }
                             break;
                         case "log/data":
                             SocketLogMessage lg;
                             lg = new SocketLogMessage(subMsg);
                             if (_processingMessages.Count > 0)
                             {
                                 string eventMsg = _processingMessages[0];
                                 _processingMessages.RemoveAt(0);
                                 lg.FullMessage = eventMsg;
                                 msgs.Enqueue(lg);
                             }
                             else
                             {
                                 _processingMessages.Insert(0, origMsg);
                                 _processingMessages.Insert(1, subMsg);
                                 break;
                             }
                             break;
                         case "text/disconnect-notice":
                             msgs.Enqueue(new DisconnectNoticeMessage(origMsg));
                             break;
                         case "auth/request":
                             msgs.Enqueue(new AuthenticationRequestMessage(origMsg));
                             break;
                         default:
                             if (_disposeInvalidMesssage != null)
                                 _disposeInvalidMesssage(origMsg);
                             break;
                     }
                 }
                 if (msgs.Count > 0)
                     _processMessageQueue(msgs);
                 lock (_processingMessages)
                 {
                     lock (_splitMessages)
                     {
                         if (_splitMessages.Count > 0)
                         {
                             while (_splitMessages.Count > 0)
                             {
                                 _processingMessages.Add(_splitMessages[0]);
                                 _splitMessages.RemoveAt(0);
                             }
                         }
                         else
                         {
                             run = false;
                         }
                     }
                 }
             }
         }
         lock (_splitMessages)
         {
             if (_splitMessages.Count == 0)
                 _mreMessageWaiting.Reset();
         }
     }
 }
 protected override void _preSocketReady()
 {
     _isHungup = false;
     _awaitingCommands = new Queue<ManualResetEvent>();
     BufferedStream _in = new BufferedStream(new NetworkStream(socket));
     _sendCommand("connect");
     _properties = ASocketMessage.ParseProperties(ReadMessage(_in));
     string[] keys = new string[_properties.Count];
     _properties.Keys.CopyTo(keys, 0);
     foreach (string str in keys)
     {
         string val = _properties[str];
         _properties.Remove(str);
         _properties.Add(str, Uri.UnescapeDataString(val));
     }
     _sendCommand("linger");
     ReadMessage(_in);
     _sendCommand("api strftime %Y-%m-%d-%H-%M");
     string[] split = new CommandReplyMessage(ReadMessage(_in)).ReplyMessage.Split('-');
     _startTime = new DateTime(int.Parse(split[0]), int.Parse(split[1]), int.Parse(split[2]), int.Parse(split[3]), int.Parse(split[4]), 0);
     RegisterEvent(CHANNEL_END_EVENT_NAME);
     RegisterEvent(EXECUTE_COMPLETE_EVENT_NAME);
 }