#c# #.net
Вопрос:
Я пытаюсь перенаправить вывод dotnet-счетчика для отображения в веб-приложение, однако возникает недопустимое исключение, вот мой код:
var startinfo = new ProcessStartInfo( "dotnet-counters" )
{
Arguments = $"monitor --process-id 1",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
};
var process = new Process { StartInfo = startinfo };
process.OutputDataReceived = OnReceived;
process.ErrorDataReceived = OnReceived;
process.Exited = OnExist;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
При запуске процесса из стандартного вывода считывается сообщение об ошибке:
Необработанное исключение: Система.Исключение InvalidOperationException: Не удается увидеть, была ли нажата клавиша, когда в приложении нет консоли или когда ввод консоли был перенаправлен из файла. Попробуйте Console.In.Заглянуть
Похоже, что стандартный вывод не может перенаправить таким образом, есть идеи?
Комментарии:
1. вы спрашиваете о перенаправлении вывода ; но ошибка связана с вводом . Работает ли это, если вы удалите
ReadLine()
функции?2. @Felix если строки BeginOutputReadLine и BeginErrorReadLine удалены,вывод больше недоступен
3. подождите — ваша переменная есть
process
, но вы вызываете функции в классеProcess
. разве вы не получаете ошибку компиляции? (Я так и делаю)
Ответ №1:
Существует альтернатива перенаправлению выходных данных из инструмента. dotnet-counters
Инструмент использует EventCounter
класс под колпаками (источник). Значения System.Runtime
, в частности, передаются поставщиком событий.
Хорошо то, что эти счетчики можно считывать вне процесса, как это делает инструмент. Это означает, что вы можете написать свой собственный код для прослушивания этих счетчиков и отображения их на веб-странице с некоторым кодом, подобным этому:
var processId = xxxx;
var providers = new List<EventPipeProvider>()
{
new EventPipeProvider("System.Runtime",
EventLevel.Informational, arguments: new Dictionary<string, string>
{
{"EventCounterIntervalSec", "1"}
})
};
var client = new DiagnosticsClient(processId);
using (var session = client.StartEventPipeSession(providers, false))
{
var source = new EventPipeEventSource(session.EventStream);
source.Dynamic.All = obj =>
{
if (obj.EventName == "EventCounters")
{
var payload = (IDictionary<string, object>)obj.PayloadValue(0);
Console.WriteLine(string.Join(", ", payload.Select(p => $"{p.Key}: {p.Value}")));
}
};
source.Process();
}
Приведенный выше код показывает исходные данные:
Полезная нагрузка: { имя:»ЦП-использование», «отображаемое имя»:»ЦП», в смысле:0, StandardDeviation:0, посчитайте:1, минимум:0, максимум:0, IntervalSec:1.0001626, серия:»интервал=1000″, аналог инженерной:»значит», метаданные:»», DisplayUnits:»%» }
полезная нагрузка: { имя:»рабочего набора», «отображаемое имя»:»рабочий набор», значит:54, StandardDeviation:0, посчитайте:1, мин:54, Макс:54, IntervalSec:1.0001626, серия:»интервал=1000″, аналог инженерной:»значит», метаданные:»», DisplayUnits:»МБ» }
полезная нагрузка: { название:»ГК» кучи «размер», «отображаемое имя»:»ГК» кучи «размер», подразумеваем:1, StandardDeviation:0, посчитайте:1, мин:1, Макс:1, IntervalSec:1.0001626, серия:»интервал=1000″, аналог инженерной:»значит», метаданные:»», DisplayUnits:»МБ» }
полезная нагрузка: { имя:»поколения-0-ГК-граф», «отображаемое имя»:»поколения 0″, «ГК Граф», DisplayRateTimeScale:»00:01:00″, инкремент:1, IntervalSec:1.0001626, «метаданные»:»», серия:»интервал=1000″, аналог инженерной:»сумма», DisplayUnits:»» }
полезная нагрузка: { название:»ген-1-ГК-граф», «отображаемое имя»:»ген. 1 ГК Граф», DisplayRateTimeScale:»00:01:00″, инкремент:0, IntervalSec:1.0001626, «метаданные»:»», серия:»интервал=1000″, аналог инженерной:»сумма», DisplayUnits:»» }
полезная нагрузка: { имя:»ген-2-ГК-граф», «отображаемое имя»:»ген 2 ГК Граф», DisplayRateTimeScale:»00:01:00″, инкремент:0, IntervalSec:1.0001626, «метаданные»:»», серия:»интервал=1000″, аналог инженерной:»сумма», DisplayUnits:»» }
Ответ №2:
Проблема не в вашем коде, а в программе, которую вы пытаетесь запустить. Очевидно, он использует консоль.Ключ чтения, который не разрешен при перенаправлении стандартного ввода.
Из документации:
Исключения
Исключение недействительной операции
Свойство In перенаправляется из какого-либо потока, отличного от консоли.
Единственный способ избежать этой ошибки-избежать перенаправления ввода. Так что измените это
RedirectStandardInput = true
к этому
RedirectStandardInput = false
Комментарии:
1. тот же результат,вы могли бы попробовать