Multithreading 如何停止无限线程
我有一个powershell脚本,它使用无限循环创建两个线程(仅作为示例) 当我按下Multithreading 如何停止无限线程,multithreading,powershell,Multithreading,Powershell,我有一个powershell脚本,它使用无限循环创建两个线程(仅作为示例) 当我按下Ctrl+Z时,它试图杀死所有线程。 但它没有成功: 为了创建线程,我使用了BeginInvoke,当我想停止它时,我使用了EndInvoke 问题在于,根据,EndInvoke将等待线程的BeginInvoke完成,但线程不会完成,因为它有无限循环: 等待挂起的异步BeginInvoke完成 当用户按下Ctrl+Z时,如何杀死所有线程 我读到了一个类似的问题: 但它正在使用同样使用EndInvoke的管道
Ctrl+Z
时,它试图杀死所有线程。但它没有成功:
为了创建线程,我使用了
BeginInvoke
,当我想停止它时,我使用了EndInvoke
问题在于,根据,
EndInvoke
将等待线程的BeginInvoke
完成,但线程不会完成,因为它有无限循环:
等待挂起的异步BeginInvoke完成
当用户按下Ctrl+Z
时,如何杀死所有线程
我读到了一个类似的问题:但它正在使用同样使用
EndInvoke
的管道
这是PowerShell中的一个小脚本,演示了我上面写的内容:
function Invoke-Main(){
[scriptblock]$code = {
while($true){
Start-Sleep 2
Write-Host "TID: "$([System.Threading.Thread]::CurrentThread.ManagedThreadId)
}
}
#requires -Version 2
function Test-KeyPress
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Windows.Forms.Keys[]]
$Keys
)
# use the User32 API to define a keypress datatype
$Signature = @'
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern short GetAsyncKeyState(int virtualKeyCode);
'@
$API = Add-Type -MemberDefinition $Signature -Name 'Keypress' -Namespace Keytest -PassThru
# test if each key in the collection is pressed
$Result = foreach ($Key in $Keys)
{
[bool]($API::GetAsyncKeyState($Key) -eq -32767)
}
# if all are pressed, return true, if any are not pressed, return false
$Result -notcontains $false
}
function Kill-AllThreadsOnKeyBreak($Jobs){
Start-Sleep -Seconds 1
$ctrlZPressed = $false
if($host.name -eq 'ConsoleHost'){
if ([console]::KeyAvailable)
{
$key = [system.console]::readkey($true)
if (($key.modifiers -band [consolemodifiers]"control") -and ($key.key -eq "Z"))
{
$ctrlZPressed = $true
}
}
}
else{
$ctrlZPressed = Test-KeyPress -Keys ([System.Windows.Forms.Keys]::ControlKey),([System.Windows.Forms.Keys]::Z)
}
if ($ctrlZPressed){
"Terminating..."
ForEach ($Job in $Jobs){
Write-Host "[START] EndInvoke"
$Job.Thread.EndInvoke($Job.Handle)
Write-Host "[END] EndInvoke"
$Job.Thread.Dispose()
$Job.Thread = $Null
$Job.Handle = $Null
$ResultTimer = Get-Date
}
Write-Verbose "Termination completed"
}
}
$SleepTimer = 200
$MaxResultTime = 120
$MaxThreads = 3
$ISS = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads, $ISS, $Host)
$RunspacePool.Open()
$Jobs = @()
[array]$computerList = @("Computer1", "Computer2")
foreach($computera in $computerList){
$PowershellThread = [powershell]::Create().AddScript($code)
$PowershellThread.RunspacePool = $RunspacePool
$Handle = $PowershellThread.BeginInvoke()
$Job = "" | Select-Object Handle, Thread, object
$Job.Handle = $Handle
$Job.Thread = $PowershellThread
$Job.Object = $computer
$Jobs += $Job
}
While (@($Jobs | Where-Object {$_.Handle -ne $Null}).count -gt 0) {
Kill-AllThreadsOnKeyBreak $Jobs
Start-Sleep -Milliseconds $SleepTimer
}
$RunspacePool.Close() | Out-Null
$RunspacePool.Dispose() | Out-Null
}
Invoke-Main
我重新检查了方法
Stop
,将$Job.Thread.EndInvoke()
替换为$Job.Thread.Stop()
后,该方法工作正常
可以找到对该命令的引用。据微软称: 同步停止当前正在运行的命令