Very infrequently (less than 0.1% of function calls) I see an exception from inside a function. The function writes a log entry to a common log file and the intent is that it will wait until it can obtain the mutex that controls writing to the common file.
Relevant code snippet:
function WriteSummary ([string]$fnContent)
{
$fnTimeStamp = Get-Date -Format "HH:mm:ss.ff"
Try {
[void]$SummaryLogMutex.WaitOne()
[System.IO.File]::AppendAllText($script:SummaryLog,("$fnTimeStamp $fnContent") + ([Environment]::NewLine))
} Catch {
$FullException = ($_ | Format-List -Force | Out-String)
WriteActivity -fnContent ("$FullException")
} Finally {
[void]$SummaryLogMutex.ReleaseMutex()
}
}
$SummaryLogMutex = New-Object System.Threading.Mutex($false, "Global\SummaryLogMutex")
WriteSummary -fnContent ("Some text")
The exception is as follows:
Exception : System.Management.Automation.RuntimeException: You
cannot call a method on a null-valued expression.
at System.Management.Automation.ExceptionHandlingOps
.CheckActionPreference(FunctionContext funcContext,
Exception exception)
at System.Management.Automation.Interpreter.ActionCa
llInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTry
CatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTry
CatchFinallyInstruction.Run(InterpretedFrame frame)
The trace indicates it is "[void]$SummaryLogMutex.WaitOne()" causing the exception.
I would be grateful for help with understanding and resolving what is going on.
Modified code to be tested to create object inside try block and avoid invoking method on variable set to null:
function WriteSummary ([string]$fnContent)
{
$fnTimeStamp = Get-Date -Format "HH:mm:ss.ff"
Try {
If (!$script:SummaryLogMutex) {
$script:SummaryLogMutex = New-Object System.Threading.Mutex($false, "Global\SummaryLogMutex")
WriteActivity -fnContent ("Created Summary Log Mutex")
}
[void]$script:SummaryLogMutex.WaitOne()
[System.IO.File]::AppendAllText($script:SummaryLog,("$fnTimeStamp $fnContent") + ([Environment]::NewLine))
} Catch {
$FullException = ($_ | Format-List -Force | Out-String)
WriteActivity -fnContent ("$FullException")
} Finally {
[void]$script:SummaryLogMutex.ReleaseMutex()
}
}
WriteSummary -fnContent ("Some text")