Как обработать многострочное сообщение с помощью process.OutputDataReceived?

#c#

#c#

Вопрос:

Я написал код, который получает данные от процесса и обрабатывает их в OutputDataReceived . Это не работает при получении многострочного сообщения. Каждая строка вызывает отдельный вызов OutputDataReceived , а затем startSequence и endSequence не найдены в одном сообщении, что не приводит к совпадению.

Каков хороший способ решить эту проблему?

 process.OutputDataReceived  = (object sender, DataReceivedEventArgs e) =>
{
  if (!String.IsNullOrEmpty(e.Data))
  {
    err = OnOutputDataReceived(e.Data);
  }
};

private string OnOutputDataReceived(string data)
{
  string startSeq = "|-->";
  string delimiterSeq = "<-->";
  string endSeq = "<--|";
  string pattern = @"|-->.*?<--|";
  RegexOptions options = RegexOptions.Singleline;
  Match match = Regex.Match(data, pattern, options);

  while (match.Success)
  {
    string trimmedValue = match.Value.Replace(startSeq, "").Replace(endSeq, "");
    string[] messageParts = trimmedValue.Split(new string[] { delimiterSeq }, System.StringSplitOptions.None);
    int minValidMessageParts = 3;
    Console.WriteLine(messageParts);
    if (messageParts.Length >= minValidMessageParts)
    {
      string messageType = messageParts[1];

      if (messageType == "Progress")
      {
        string incrementStr = messageParts[3];
        int.TryParse(incrementStr, out int increment);
        OnProgressCallback(this, new ProgressCallbackEventArgs(increment));
      }
      else if (messageType == "Fatal")
      {
        string messageText = messageParts[2];
        return String.Format("Conversion failed: {0}", messageText);
      }
    }

    match = match.NextMatch();
  }

  return null;
}
  

Комментарии:

1. Настройте свой код так, чтобы он запоминал предыдущие строки (например, добавлял их в список string) и просматривал их при каждом полученном outputdatareceived и пытался найти начало и конец в списке. Очищайте список / запускайте действие для обработки содержимого списка только тогда, когда в списке найдены начало и конец

2. Вы просто заменяете начальную и конечную последовательности. Они просто игнорируются. Почему вы говорите, что это проблема?

Ответ №1:

Вы можете попробовать что-то вроде этого:

 StringBuilder output = new StringBuilder();
process.OutputDataReceived  = (object sender, DataReceivedEventArgs e) =>
{
  if (!String.IsNullOrEmpty(e.Data))
  {
    output.Add(e.Data);
    err = OnOutputDataReceived(output.ToString());
  }
};
  

Хотя это может быть немного сложно, поскольку он сканирует весь вывод всякий раз, когда добавляется одна строка… Вы должны иметь возможность легко ограничивать в зависимости от ваших требований, т. Е. Передавать только последние X строк или все, что вам требуется?