public virtual void ProcessOutputQueue() { if (_ProcessingOutputQueue) { return; } using (new UsingProcessor(() => StartProcessOutputQueue(), () => EndProcessOutputQueue())) { var doc = Document; if (doc == null) { return; //Process queue in next call to ProcessOutputQueue(), when document will be available. } if (OutputQueue.Count <= 0) { return; } var sync = SynchronizeInvoke; DoProcessQueue(); void DoProcessQueue() { var bufferOutput = new StringBuilder(DefaultBufferCapacity); while (OutputQueue.Count > 0) { var output = OutputQueue.Dequeue(); if (output == null) { continue; } //Merge output parts with same formatting if (OutputQueue.Count > 0) { var nextOutput = OutputQueue.Peek(); if (nextOutput?.IsFormattingEqual(output) ?? false) { bufferOutput.Append(output.Text); continue; } } bufferOutput.Append(output.Text); if (bufferOutput.Length > 0) { try { ProcessBuffer(doc, sync, output, bufferOutput); } catch (Exception ex) { ReportErrorSynchronized(doc, sync, ex.Message); } } } } } }
// runs in its own thread, started from Connect() void IoThread() { string outputLine = ""; lastMessageSent = DateTime.UtcNow; do { try { ActualBotNick = desiredBotNick; reconnect = false; Logger.Log(LogType.IRC, "Connecting to {0}:{1} as {2}", hostName, port, ActualBotNick); Connect(); // register Send(IRCCommands.User(ActualBotNick, 8, ConfigKey.ServerName.GetString())); Send(IRCCommands.Nick(ActualBotNick)); while (isConnected && !reconnect) { Thread.Sleep(10); if (localQueue.Length > 0 && DateTime.UtcNow.Subtract(lastMessageSent).TotalMilliseconds >= SendDelay && localQueue.Dequeue(ref outputLine)) { writer.Write(outputLine + "\r\n"); lastMessageSent = DateTime.UtcNow; writer.Flush(); } if (OutputQueue.Length > 0 && DateTime.UtcNow.Subtract(lastMessageSent).TotalMilliseconds >= SendDelay && OutputQueue.Dequeue(ref outputLine)) { writer.Write(outputLine + "\r\n"); lastMessageSent = DateTime.UtcNow; writer.Flush(); } if (client.Client.Available > 0) { string line = reader.ReadLine(); if (line == null) { break; } HandleMessage(line); } } } catch (SocketException) { Logger.Log(LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000); reconnect = true; } catch (IOException) { Logger.Log(LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000); reconnect = true; #if !DEBUG } catch (Exception ex) { Logger.Log(LogType.Error, "IRC: {0}", ex); reconnect = true; #endif } if (reconnect) { Thread.Sleep(ReconnectDelay); } } while(reconnect); }
public override void ProcessOutputQueue() { if (_ProcessingOutputQueue) { return; } lock (_SyncObject) { using (new UsingProcessor(() => StartProcessOutputQueue(), () => EndProcessOutputQueue())) { var doc = Document; if (doc == null) { return; //Process queue in next call to ProcessOutputQueue(), when document will be available. } if (OutputQueue.Count <= 0) { return; } var sync = SynchronizeInvoke; DoProcessQueue(); void DoProcessQueue() { var bufferOutput = new StringBuilder(DefaultBufferCapacity); while (OutputQueue.Count > 0) { var output = OutputQueue.Dequeue(); if (output == null) { continue; } //Merge output parts with same formatting if (OutputQueue.Count > 0) { var nextOutput = OutputQueue.Peek(); if (nextOutput?.IsFormattingEqual(output) ?? false) { if (!output.Text.StartsWith("\r")) { bufferOutput.Append('\r'); } bufferOutput.Append(output.Text); continue; } } //Should every output start with CR, i.e. clear last line in output? //Test sample in R: /* * SEQ <- seq(1,100) * pb <- txtProgressBar(1, 100, style = 3) * TIME <- Sys.time() * for (i in SEQ) { * Sys.sleep(0.1) * setTxtProgressBar(pb, i) * } */ if (!output.Text.StartsWith("\r")) { bufferOutput.Append('\r'); } bufferOutput.Append(output.Text); var text = bufferOutput.ToString(); bufferOutput.Clear(); //\r without following \n clears current line (paragraph) var parts = Regex.Split(text, "\r(?!\n)"); var bufferParts = new StringBuilder(1024); for (int i = 0; i < parts.Length; i++) { var part = parts[i]; if (i < parts.Length - 1) { //Remove last line var nindex = part.LastIndexOf('\n'); if (nindex >= 0) { part = part[..(nindex + 1)];