private void DoSend() { Chat = new ChatClientStable(chatCallback, TerminalBindings.Chat); Chat.Connected += () => { if (Connected != null) { Connected(); } }; Chat.Disconnected += () => { if (Disconnected != null) { Disconnected(); } }; UserInfoSource = new UserInfoExCache(TradeSharpAccountStatistics.Instance.proxy); while (!isStopping) { bool timeoutFlag; var allRequests = requests.ExtractAll(lockTimeout, out timeoutFlag); if (timeoutFlag) { continue; } // флаг повтора запроса; // перезапросы возникают из-за ошибок сети; // в этом случае ожидание между запросами увеличено, чтобы не загружать проц без пользы var repeatRequest = false; foreach (var request in allRequests) { try { switch (request.Code) { case RequestCode.GetAllUsers: request.Id = Chat.GetAllUsers((string)request.Arguments[0]); break; case RequestCode.Enter: request.Id = Chat.Enter((User)request.Arguments[0]); break; case RequestCode.Exit: request.Id = Chat.Exit(); break; case RequestCode.GetRooms: request.Id = Chat.GetRooms(); break; case RequestCode.EnterRoom: request.Id = Chat.EnterRoom((string)request.Arguments[0], (string)request.Arguments[1]); break; case RequestCode.MoveToRoom: request.Id = Chat.MoveToRoom((int)request.Arguments[0], (string)request.Arguments[1], (string)request.Arguments[2]); break; case RequestCode.LeaveRoom: request.Id = Chat.LeaveRoom((string)request.Arguments[0]); break; case RequestCode.CreateRoom: request.Id = Chat.CreateRoom((Room)request.Arguments[0]); break; case RequestCode.DestroyRoom: request.Id = Chat.DestroyRoom((string)request.Arguments[0]); break; case RequestCode.SendPrivateMessage: request.Id = Chat.SendPrivateMessage((int)request.Arguments[0], (string)request.Arguments[1]); break; case RequestCode.SendMessage: request.Id = Chat.SendMessage((string)request.Arguments[0], (string)request.Arguments[1]); break; case RequestCode.GetPendingMessages: request.Id = Chat.GetPendingMessages((DateTime)request.Arguments[0], (string)request.Arguments[1]); break; case RequestCode.GetPendingPrivateMessages: request.Id = Chat.GetPendingPrivateMessages((DateTime)request.Arguments[0], (int)request.Arguments[1]); break; case RequestCode.Ping: Chat.Ping(); break; case RequestCode.GetUserInfoEx: var userinfo = UserInfoSource.GetUserInfo((int)request.Arguments[0]); if (UserInfoExReceived != null) { UserInfoExReceived(userinfo ?? new UserInfoEx { Id = (int)request.Arguments[0] }); } break; case RequestCode.SetUserInfoEx: UserInfoSource.SetUserInfo((UserInfoEx)request.Arguments[0]); break; } if (request.Id == 0) { QueueRequest(request); // if server refused request - try again repeatRequest = true; } else if (request.Id != -1) // skip Ping, GetUserInfoEx, SetUserInfoEx { request.Status = ChatResultCode.InProgress; pendingRequests.UpdateValues(request.Id, request); /*if (pendingRequestsLock.TryEnterWriteLock(lockTimeout)) * { * pendingRequests.Add(request.Id, request); * pendingRequestsLock.ExitWriteLock(); * } * else * Console.WriteLine("ChatSender.DoSend: pendingRequestsWriteLock timeout");*/ var requestCopy = new ChatRequest(request); if (RequestQueuedOnServer != null) { RequestQueuedOnServer(requestCopy); } if (forwardAnswers.ContainsKey(request.Id)) { pendingRequests.Remove(request.Id); requestCopy.Status = forwardAnswers.ReceiveValue(request.Id); if (RequestProcessed != null) { RequestProcessed(requestCopy); } forwardAnswers.Remove(request.Id); } } } catch (Exception ex) // probably communication error { Logger.ErrorFormat("DoSend exception: {0}", ex); if (request.Code != RequestCode.Ping) { QueueRequest(request); } repeatRequest = true; } } //проверка соединения - ping if (allRequests.Count == 0) { if (DateTime.Now.Subtract(lastConnectionCheck.GetLastHit()).TotalSeconds > 15) { var request = new ChatRequest(RequestCode.Ping, new List <object>(), -1); QueueRequest(request); lastConnectionCheck.Touch(); } } Thread.Sleep(repeatRequest ? 1000 : 100); } }