加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – PowerShell:DownloadFileAsync的Runspace问题

发布时间:2020-12-14 05:11:23 所属栏目:Java 来源:网络整理
导读:我需要在Power Shell 2.0中使用WebClient下载文件,我想显示下载进度,所以我这样做: $activity = "Downloading"$client = New-Object System.Net.WebClient$urlAsUri = New-Object System.Uri($url)$event = New-Object System.Threading.ManualResetEvent($
我需要在Power Shell 2.0中使用WebClient下载文件,我想显示下载进度,所以我这样做:
$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()

我收到一个错误没有可用Runspace在此线程中运行脚本.对于$downloadProgress处理程序中的代码,这是逻辑的.但是,如何为(可能)属于ThreadPool的线程提供Runspace?

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

解决方法

谢谢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:tempie9-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的powerhell可以帮助你在这里,但你可以转换一个异步回调到一个简单的管道事件,然后处理该事件使用常规事件.我在http://poshcode.org/1382发布了一个脚本(New-ScriptBlockCallback)

希望这可以帮助,

-Oisin

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读