Как cmdlet знает, когда он действительно должен звонить WriteVerbose()
, WriteDebug()
и и т.д.?
Возможно, я пропускаю что-то простое, но я не могу найти ответ. Все cmdlet реализации я видел до сих пор просто вызов WriteVerbose()
без любого колебания. Я знаю, что это корректно, чтобы сделать так, но это не эффективно.
Производительность страдает, когда подробный режим выключен, но cmdlet все еще готовит данные к WriteVerbose()
ни к чему призовите, то есть.
Другими словами, в cmdlet я хотел бы смочь к:
if (<VerboseMode>)
{
.... data preparation, sometimes expensive ...
WriteVerbose(...);
}
Но я не знаю, как получить это if (<VerboseMode>)
. Какие-либо идеи?
Заключение: ответ @stej показывает, как получают запрошенную информацию в теории. На практике это - hacky и вряд ли подходящий. Таким образом, если cmdlet производит действительно дорогой подробный или вывод отладки затем, выглядит разумным представить дополнительный параметр, указывающий уровни многословия.
Это метод из System.Management.Automation.MshCommandRuntime
.
internal void WriteVerbose(VerboseRecord record)
{
if ((this.Host == null) || (this.Host.UI == null))
{
tracer.TraceError("No host in CommandBase.WriteVerbose()", new object[0]);
throw tracer.NewInvalidOperationException();
}
ActionPreference verbosePreference = this.VerbosePreference;
if (this.WriteHelper_ShouldWrite(verbosePreference, this.lastVerboseContinueStatus))
{
if (record.InvocationInfo == null)
{
record.SetInvocationInfo(this.MyInvocation);
}
this.CBhost.InternalUI.WriteVerboseRecord(record);
}
this.lastVerboseContinueStatus = this.WriteHelper(null, null, verbosePreference, this.lastVerboseContinueStatus, "VerbosePreference");
}
MshCommandRuntime
реализует интерфейс ICommandRuntime
, который ничего не знает о многословности: | (обнаруживается через отражатель). Экземпляр MshCommandRuntime
должен быть доступен в командлете
( public ICommandRuntime CommandRuntime {get; set;}
).
Таким образом, должно быть возможно преобразовать свойство CommandRuntime
в MshCommandRuntime
и проверить степень детализации. Во всяком случае, это действительно некрасиво.
Я полностью согласен с тем, что должен быть простой способ узнать это. Кроме того, компилятор (мечтающий) должен быть достаточно умен, чтобы не оценивать некоторые строки в таких случаях:
$DebugPreference = 'SilentlyContinue'
$array = 1..1000
Write-Debug "my array is $array"
Вход в Write-Debug
никогда не будет использоваться, поэтому $ array
не должен 'не оценивается в переданной строке .. (можно проверить, что это действительно оценивается следующим образом: Write-Debug "мой массив - $ ($ array |% {write-host $ _; $ _}) "