Timer event causing the script to hang

I have a script where in i have two timers. One to print logger every 1 sec. And other timer which checks for ctrl-c pressed and unsubscribes both the timers.

# Disables the timer and unregisters the event subscriber
function RemoveTimer ($timerin, $sourceidentifier) {
	try {
		$timerin.Enabled = $False
		Unregister-Event -SourceIdentifier $sourceidentifier
	} Catch {
		Write-Host "Error occurred while stopping timer $($_.Exception.Message)"
	}
}

# LMD Timer
try {
	$global:lmdtimer = New-Object Timers.Timer
	$lmdtimer.Interval = 1000
	$registerevent = Register-ObjectEvent -InputObject $lmdtimer -EventName Elapsed -SourceIdentifier LMDTimer.Output -Action {
		Write-Debug "$($Event | Out-String)"
		Write-Host "Script is running"
	}
	$lmdtimer.Enabled = $True
	Write-Debug "$($lmdtimer | Out-String)"
} Catch {
    Write-Host "Error occurred while starting LMDTimer $($_.Exception.Message)"
	RemoveTimer $lmdtimer "LMDTimer.Output"
}

# CTRLC Timer
try {
	[console]::TreatControlCAsInput = $true
	$global:ctrlctimer = New-Object Timers.Timer
	$ctrlctimer.Interval = 1000
	$registerevent = Register-ObjectEvent -InputObject $ctrlctimer -EventName Elapsed -SourceIdentifier CTRLCTimer.Output -Action {
		if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
		{
		  Write-Debug "$($Event | Out-String)"
		  Write-Host "Removing LMDTimer and CTRLCTimer"
		  try {
			  $lmdtimer.Enabled = $False
			  Unregister-Event -SourceIdentifier "LMDTimer.Output"
			  $ctrlctimer.Enabled = $False
			  Unregister-Event -SourceIdentifier "CTRLCTimer.Output"
		  } Catch {
			  Write-Host $_.Exception.Message
		  }
		  Write-Host "Removing TreatControlCAsInput"
		  [console]::TreatControlCAsInput = $false
		  exit
		}
	}
	$ctrlctimer.Enabled = $True
	Write-Debug "$($ctrlctimer | Out-String)"
} Catch {
    Write-Host "Error occurred while starting CTRLCTimer $($_.Exception.Message)"
	RemoveTimer $ctrlctimer "CTRLCTimer.Output"
	[console]::TreatControlCAsInput = $false
}

for ($i=0;$i -lt 5000;$i++) {
	Write-Host "$i"
}

RemoveTimer $lmdtimer "LMDTimer.Output"
RemoveTimer $ctrlctimer "CTRLCTimer.Output"
[console]::TreatControlCAsInput = $false

While the script continues to run. In the midst if i press Ctrl-C this script just prints the below and hangs. This happens sometimes and not every time. 

"Removing LMDTimer and CTRLCTimer"

  • Edited by pk_hafeez 19 hours 34 minutes ago
May 27th, 2015 6:38am

I have a requirement where the timer cannot be single-shot. Both to be run at regular intervals :(

Anytime i press a ctrl-c continously, the timer should capture this and end the powershell script and the logger timer..

May 27th, 2015 12:11pm

The solution is still the same.  Use a properly scoped variable.

Free Windows Admin Tool Kit Click here and download it now
May 27th, 2015 12:38pm

My variables both are global scoped. And the script is working fine. Only in few situations, on Ctrl-C it hangs.
May 27th, 2015 1:29pm

You will have to do some serious debugging to discover why it is hanging.  Wht you are trying to do is not really supported in PowerShell or in WPF. YOu are on your own to find fixes and work-arounds.

Why do you need to use Ctl-C. Why not use a button to abort.  It sounds to me like an overall design issue. 

Free Windows Admin Tool Kit Click here and download it now
May 27th, 2015 1:53pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics