Skip to content

Instantly share code, notes, and snippets.

@JustinGrote
Last active May 2, 2025 14:30
Show Gist options
  • Save JustinGrote/942f26502904da24c74b466d298e810e to your computer and use it in GitHub Desktop.
Save JustinGrote/942f26502904da24c74b466d298e810e to your computer and use it in GitHub Desktop.
"Await" one or more tasks in PowerShell in a cancellable manner (e.g. ctrl-c still works)
using namespace System.Threading.Tasks
using namespace System.Collections.Generic
filter Receive-Task {
#Wait on one or more tasks in a cancellable manner
[CmdletBinding()]
param(
[parameter(Mandatory, ValueFromPipeline)][Task]$Task,
#How long to wait before checking for a cancellation in milliseconds
[int]$WaitInterval = 500
)
begin {
[List[Task]]$Tasks = @()
}
process {
$Tasks.Add($Task)
}
end {
while ($Tasks.count -gt 0) {
$completedTaskIndex = [Task]::WaitAny($Tasks, $WaitInterval)
if ($completedTaskIndex -eq -1) {
#Timeout occured, this provides an opportunity to cancel before waiting again
continue
}
$completedTask = $Tasks[$completedTaskIndex]
$Tasks.RemoveAt($completedTaskIndex)
#We use this instead of .Result so we get a proper exception if one was thrown instead of AggregateException
#Reference: https://stackoverflow.com/questions/17284517/is-task-result-the-same-as-getawaiter-getresult/38530225#38530225
$completedTask.GetAwaiter().GetResult()
}
}
}
@scriptingstudio
Copy link

filter seems to be a misprint. Is it? Should be function. I'm aware what filter is

@JustinGrote
Copy link
Author

filter seems to be a misprint. Is it? Should be function. I'm aware what filter is

Doesn't make much of a difference either way. Anyways, this gist has been replaced by my ThreadJob module that I recommend instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment