gpt4 book ai didi

multithreading - PowerShell:DownloadFileAsync 的运行空间问题

转载 作者:行者123 更新时间:2023-12-04 01:47:54 25 4
gpt4 key购买 nike

我需要使用 WebClient 下载文件在 PowerShell 2.0 中,我想显示下载进度,所以我这样做了:

$activity = "Downloading"

$client = New-Object System.Net.WebClient
$urlAsUri = New-Object System.Uri($url)

$event = New-Object System.Threading.ManualResetEvent($false)

$downloadProgress = [System.Net.DownloadProgressChangedEventHandler] {
$progress = [int]((100.0 * $_.BytesReceived) / $_.TotalBytesToReceive)
Write-Progress -Activity $activity -Status "${progress}% done" -PercentComplete $progress
}

$downloadComplete = [System.ComponentModel.AsyncCompletedEventHandler] {
Write-Progress -Activity $activity -Completed
$event.Set()
}

$client.add_DownloadFileCompleted($downloadComplete)
$client.add_DownloadProgressChanged($downloadProgress)

Write-Progress -Activity $activity -Status "0% done" -PercentComplete 0
$client.DownloadFileAsync($urlAsUri, $file)

$event.WaitOne()

我收到一个错误 There is no Runspace available to run scripts in this thread.对于 $downloadProgress 中的代码处理程序,这是合乎逻辑的。但是,我如何提供 Runspace对于(可能)属于 ThreadPool 的线程?

更新:
请注意,这个问题的两个答案都值得一读,如果可以的话,我都会接受。

最佳答案

感谢 stej 的点头。

Andrey,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 中另一个棘手的领域是异步回调。在 powershell 的 v1 或 v2 中没有任何东西可以直接帮助您,但是您可以使用一些简单的管道将异步回调转换为事件,然后使用常规事件处理该事件。我在 http://poshcode.org/1382 上发布了一个脚本(New-ScriptBlockCallback)

希望这有帮助,

-Oisin

关于multithreading - PowerShell:DownloadFileAsync 的运行空间问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4926060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com