BeginInvoke() 返回的 AsynchronousObject 的 IsComplete 全部为真
IsComplete of AsynchronousObject returned by BeginInvoke() all true
我目前正在学习 Powershell 中的 运行spaces(我的最终目标是建立一个作业调度系统)来做到这一点我写了一个基本的脚本来学习和使用 运行空格。
我期望发生的事情:
我预计当我 运行 代码到注释行时,这将在 RunspacePool 中排队 8 个作业和 运行 它们,运行 最多一次 2 个。
运行 单行 $JobList.AsynchronousObject
几次,然后应该看到越来越多的 IsComplete
标志从 false
变为 true
作为工作由于 Start-Sleep
命令,它们每个需要 20 秒才能完成。
BeginInvoke
命令显然 returns 一个实现 IAsycResult
接口的对象。
在 IAsyncResult
的评论中提到轮询 IsComplete
属性 以查看异步操作是否已完成,尽管这并不理想,但我在下面出于学习目的尝试这样做.
实际:
所有 IsComplete
标志在 运行 代码顶部 true
秒后出现,这不是我所期望的
问题:
IsComplete
标志是否仅表示脚本是否已开始执行,也许这就是为什么它们在排队后 true
秒后全部出现的原因?
对于任何人能够提供的进一步阅读的任何帮助或参考,我深表感谢。
非常感谢
尼克
#Set up runspace
$RunspacePool = [runspacefactory]::CreateRunspacePool()
$RunspacePool.SetMinRunspaces(1)
$RunspacePool.SetMaxRunspaces(2)
#Create arraylist to hold references to all the instances running jobs
$JobList = New-Object System.Collections.ArrayList
#Queue up 8 jobs that will take 20 seconds each to complete
#Add the job details to the list so I can poll it's IsComplete property
$RunspacePool.Open()
1..8 | ForEach {
Write-Verbose "Counter: $_" -Verbose
$PowershellInstance = [powershell]::Create()
$PowershellInstance.RunspacePool = $RunspacePool
[void]$PowershellInstance.AddScript({
Start-Sleep -Seconds 20
$ThreadID = [appdomain]::GetCurrentThreadId()
Write-Verbose "$ThreadID thread completed" -Verbose
})
$AsynchronousObject = $PowershellInstance.BeginInvoke()
$JobList.Add(([PSCustomObject]@{
Id = $_
PowerShellInstance = $PowershellInstance
AsynchronousObject = $AsynchronousObject
}))
}
#----------------------------------------------
#List IsComplete should show true as jobs become complete
$JobList.AsynchronousObject
#Clean up
$RunspacePool.Close()
$RunspacePool.Dispose()
没有问题。您忘记了异步的真正含义。
当您启动异步作业时,它们不会阻塞当前线程(也就是您当前的 PowerShell 提示),它们会创建一个新线程并且 运行 从那里。异步作业的全部意义在于,您可以 运行 一次完成多个任务。
所以发生的事情是创建运行空间,一切都设置好,作业排队并开始 运行 在新线程中,然后它继续进行(一切都是异步的并且 运行ning 在单独的线程)。然后它继续执行最后三行:
#List IsComplete should show true as jobs become complete
$JobList.AsynchronousObject
#Clean up
$RunspacePool.Close()
$RunspacePool.Dispose()
这会杀死运行空间并对其进行处理,从而 "completing" 作业。
如果您 运行 注释行之前的所有内容。 然后 从 PowerShell 提示开始观察 $JobList.AsynchronousObject,然后您将看到它按预期逐步完成作业。
完成后,您可以执行最后两行来关闭和处理您的 运行空间。
如果你想让事情等着你,你必须看看作业等待功能。
我目前正在学习 Powershell 中的 运行spaces(我的最终目标是建立一个作业调度系统)来做到这一点我写了一个基本的脚本来学习和使用 运行空格。
我期望发生的事情:
我预计当我 运行 代码到注释行时,这将在 RunspacePool 中排队 8 个作业和 运行 它们,运行 最多一次 2 个。
运行 单行 $JobList.AsynchronousObject
几次,然后应该看到越来越多的 IsComplete
标志从 false
变为 true
作为工作由于 Start-Sleep
命令,它们每个需要 20 秒才能完成。
BeginInvoke
命令显然 returns 一个实现 IAsycResult
接口的对象。
在 IAsyncResult
的评论中提到轮询 IsComplete
属性 以查看异步操作是否已完成,尽管这并不理想,但我在下面出于学习目的尝试这样做.
实际:
所有 IsComplete
标志在 运行 代码顶部 true
秒后出现,这不是我所期望的
问题:
IsComplete
标志是否仅表示脚本是否已开始执行,也许这就是为什么它们在排队后 true
秒后全部出现的原因?
对于任何人能够提供的进一步阅读的任何帮助或参考,我深表感谢。
非常感谢
尼克
#Set up runspace
$RunspacePool = [runspacefactory]::CreateRunspacePool()
$RunspacePool.SetMinRunspaces(1)
$RunspacePool.SetMaxRunspaces(2)
#Create arraylist to hold references to all the instances running jobs
$JobList = New-Object System.Collections.ArrayList
#Queue up 8 jobs that will take 20 seconds each to complete
#Add the job details to the list so I can poll it's IsComplete property
$RunspacePool.Open()
1..8 | ForEach {
Write-Verbose "Counter: $_" -Verbose
$PowershellInstance = [powershell]::Create()
$PowershellInstance.RunspacePool = $RunspacePool
[void]$PowershellInstance.AddScript({
Start-Sleep -Seconds 20
$ThreadID = [appdomain]::GetCurrentThreadId()
Write-Verbose "$ThreadID thread completed" -Verbose
})
$AsynchronousObject = $PowershellInstance.BeginInvoke()
$JobList.Add(([PSCustomObject]@{
Id = $_
PowerShellInstance = $PowershellInstance
AsynchronousObject = $AsynchronousObject
}))
}
#----------------------------------------------
#List IsComplete should show true as jobs become complete
$JobList.AsynchronousObject
#Clean up
$RunspacePool.Close()
$RunspacePool.Dispose()
没有问题。您忘记了异步的真正含义。
当您启动异步作业时,它们不会阻塞当前线程(也就是您当前的 PowerShell 提示),它们会创建一个新线程并且 运行 从那里。异步作业的全部意义在于,您可以 运行 一次完成多个任务。
所以发生的事情是创建运行空间,一切都设置好,作业排队并开始 运行 在新线程中,然后它继续进行(一切都是异步的并且 运行ning 在单独的线程)。然后它继续执行最后三行:
#List IsComplete should show true as jobs become complete
$JobList.AsynchronousObject
#Clean up
$RunspacePool.Close()
$RunspacePool.Dispose()
这会杀死运行空间并对其进行处理,从而 "completing" 作业。
如果您 运行 注释行之前的所有内容。 然后 从 PowerShell 提示开始观察 $JobList.AsynchronousObject,然后您将看到它按预期逐步完成作业。
完成后,您可以执行最后两行来关闭和处理您的 运行空间。
如果你想让事情等着你,你必须看看作业等待功能。