question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add-Content and Out-File -Append can fail quietly, seemingly connected to cross-thread concurrency

See original GitHub issue

Note:

  • I don’t know what other cmdlets are affected. Update: at least Out-File -Append is affected too.

  • A common use case where the problem can surface is in the context of ForEach-Object -Parallel (while the use of Add-Content in parallel threads requires explicit synchronization, neglecting to do so should at least report the failure to write.)

Steps to reproduce

$tempFile = New-TemporaryFile
Write-Verbose -vb "Waiting for an Add-Content call to fail..."
$Error.Clear()
while ($true) {
  Remove-Item -ea Ignore $tempFile
  # Let multiple threads try to update Add-Content simultaneously.
  1..100 | ForEach-Object -Parallel { Add-Content $using:tempFile -Value $_ -ErrorAction Stop; if (-not $?) { Write-Warning $_.ToString() } }
  # On occasion, the file ends up with fewer than 100 lines.
  $countWritten = (Get-Content $tempFile).Count
  if ($countWritten -ne 100) {
    Write-Verbose -vb "$countWritten lines were written."
    # If fewer lines were written, an error should have been reported.
    $Error.Count | Should -BeGreaterOrEqual 1
  }
}
Remove-Item $tempFile

Expected behavior

The tests should run indefinitely, because the Add-Content calls should either all succeed or those that fail should report an error.

Actual behavior

A test eventually (may take a while) fails, because an Add-Content calls fails silently; e.g.:

VERBOSE: 99 lines were written.
InvalidResult:
Line |
  13 | $Error.Count | Should -BeGreaterOrEqual 1
     | Expected the actual value to be greater than or equal to 1, but got 0.

Environment data

PowerShell Core 7.2.0-preview.1

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:14 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
PaulHigincommented, Dec 15, 2020

Yes, PowerShell cmdlets are not and were never intended to be multi-threaded safe. Users must beware of using cmdlets in multiple threads, whether via foreach -parallel or PowerShell API. Same as with any non-multi-threaded-safe .NET object.

0reactions
iSazonovcommented, Sep 24, 2021

Now .Net 6.0 has get new thread-safe file IO API. https://devblogs.microsoft.com/dotnet/file-io-improvements-in-dotnet-6/#thread-safe-file-io

but I doubt that we will be able to use this.

<div> .NET Blog</div><div>File IO improvements in .NET 6</div><div>Learn about high-performance file IO features in NET 6, like concurrent reads and writes, scatter/gather IO and many more.</div>
Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found