我有一个WCF库,公开了一些有用的信息,我使用New-WebServiceProxy
cmdlet从powershell查询它们
$link = "http://localhost/Rlib/Rlib.Info.svc";
$service = New-WebServiceProxy -Uri $link;
假设我有一个像GetLastData()
这样的函数,我通常以这种方式调用它
$service.GetLastData()
现在我的功能非常慢,需要很多时间才能完成(返回日期的复杂数据库查询),我看到自动生成了异步函数,我可以使用$service.GetLastDataAsync()
调用它。它是如何工作的?一旦我调用异步方法,我如何检查数据是否可用并恢复它们?
答案 0 :(得分:2)
它是如何工作的?
GetLastDataAsync
返回Task<something>
,可用于跟踪外出操作的过程。它会变得非常复杂。除非你有充分的理由,否则你可能不需要使用异步版本?您可以将powershell作业用于同步版本,并仅轮询作业的工作方式。
一旦我调用异步方法,我该如何检查数据是否可用 恢复它们?
如果您想等待结果,可以GetLastDataAsync(..).Result
,但这没用,因为您已经可以使用同步了。
在我看来,没有简单的方法可以正确使用Task。我发现最接近的是以这种方式使用某种自定义DLL:
C:\PS> $path = "$home\Pictures\foo.png"
C:\PS> $asyncOp = [Windows.Storage.StorageFile]::GetFileFromPathAsync($path)
C:\PS> Add-Type -Path ~\PoshWinRT.dll
C:\PS> $typeName = 'PoshWinRT.AsyncOperationWrapper[Windows.Storage.StorageFile]'
C:\PS> $wrapper = new-object $typeName -Arg $asyncOp
C:\PS> $file = $wrapper.AwaitResult()
C:\PS> $file
包装器背后的理论是它在幕后使用Task.Wait
,这类似于async
的全部目的。因为它仍在阻止主线程。
<强> TLDR;坚持同步版本&amp;如果需要,可以安排工作。
https://rkeithhill.wordpress.com/2013/09/30/calling-winrt-async-methods-from-windows-powershell/
答案 1 :(得分:2)
调用Async
方法后,操作完成时会引发相应的事件(在您的情况下为GetLastDataCompleted
)。
您可以使用Register-ObjectEvent
“监听”此事件何时被提升!
我使用CDYNE's IP2Geo service进行快速测试,但这个想法与任何其他SOAP服务完全相同:
$ServiceUri = 'http://ws.cdyne.com/ip2geo/ip2geo.asmx?wsdl'
$Service = New-WebServiceProxy -Uri $ServiceUri
# Make sure the environment is clean
Remove-Variable -Scope Global -Name IPResult -Force | Out-Null
Unregister-Event -SourceIdentifier "IPResolved"
# Register an event subscription
Register-ObjectEvent -InputObject $Service -EventName ResolveIPCompleted -SourceIdentifier "IPResolved" -Action { $Global:IPResult = $args[1] } | Out-Null
# Initialize the operation with Async
$Service.ResolveIPAsync('8.8.8.8','')
# Do other stuff in the background here
# Wait for the variable to get populated
while(-not(Get-Variable -Scope Global -Name IPResult -ErrorAction SilentlyContinue)){
Start-Sleep -Seconds 1
}
# Let's see what we got!
if($Global:IPResult.Error -eq $null){
Write-Host "Success!"
# The Result property holds the result from the operation
$Global:IPResult.Result
} else {
Write-Host "Failed!"
}