Спасибо, Стей, за поклон.
Андрей, powershell имеет свой собственный пул потоков, и каждый поток службы хранит потоковый указатель на пространство выполнения (статический член System.Management.Automation.Runspaces.Runspace.DefaultRunspace предоставляет это - и будет нулевым указателем в ваших обратных вызовах.) В конечном итоге это означает, что трудно - особенно в сценариях - использовать собственный пул потоков (как это предусмотрено в .NET для асинхронных методов) для выполнения блоков сценариев.
PowerShell 2.0
Независимо от того, играть с этим не нужно, поскольку powershell v2 полностью поддерживает события:
$client = New-Object System.Net.WebClient
$url = [uri]"http://download.microsoft.com/download/6/2/F/" +
"62F70029-A592-4158-BB51-E102812CBD4F/IE9-Windows7-x64-enu.exe"
try {
Register-ObjectEvent $client DownloadProgressChanged -action {
Write-Progress -Activity "Downloading" -Status `
("{0} of {1}" -f $eventargs.BytesReceived, $eventargs.TotalBytesToReceive) `
-PercentComplete $eventargs.ProgressPercentage
}
Register-ObjectEvent $client DownloadFileCompleted -SourceIdentifier Finished
$file = "c:\temp\ie9-beta.exe"
$client.DownloadFileAsync($url, $file)
# optionally wait, but you can break out and it will still write progress
Wait-Event -SourceIdentifier Finished
} finally {
$client.dispose()
}
PowerShell v1.0
Если вы застряли на v1 (это не специально для вас, поскольку вы упомянули v2 в вопросе), вы можете использовать мою оснастку для событий PowerShell 1.0 на http://pseventing.codeplex.com/
Асинхронные обратные вызовы
Еще одна сложная область в .NET - асинхронные обратные вызовы. Здесь нет ничего такого, что могло бы помочь вам в v1 или v2 в PowerShell, но вы можете преобразовать асинхронный обратный вызов в событие с некоторой простой сантехникой, а затем обработать это событие, используя обычные события. Я разместил скрипт для этого (New-ScriptBlockCallback) на http://poshcode.org/1382
Надеюсь, это поможет,
-Oisin