2017-06-01 43 views
5

我正在使用PowerShell ISE(PS版本5.0)。如果我运行此代码:代码更改后,PowerShell ISE有时表现不可预知

Write-Host "This" 

它输出:

This 

如果我修改这样的脚本:

Write-Host "That" 

它输出:

That 

大。如预期。现在,如果我有这样的代码:

$Form = New-Object System.Windows.Forms.Form 
$Timer = New-Object System.Windows.Forms.Timer 

$Timer.Add_Tick(
{ 
    &{ 
    Write-Output "Here" 
    $Form.Close()} | Write-Host 
}) 

$Timer.Interval = 3000 
$Timer.start() 
$result = $Form.ShowDialog() 

它输出:

Here 

如果我在脚本改变什么,例如"Here""There"$Timer.Interval = 3000$Timer.Interval = 4000并运行它,它会做两件意想不到的事情:1.)不是在适当的时间内显示表单,而是在屏幕上短暂闪烁,并且2.)它会输出原始的HereThere。如果我关闭ISE并重新打开它,脚本将按预期运行。

这是怎么回事?

+0

好吧,它看起来像你没有处理对象...所以你只是创建了很多对象的实例。从新开始清除内存中的对象 – gvee

+0

当您说“运行它”时 - 是运行整个文件/代码片段,还是只运行最后一部分?在关闭一次后你不能显示表单,除非你重新实例化'$ timer',原始的事件注册仍然存在 –

+0

@gvee - 所以你说ISE持有这些对象甚至停止后?来自.NET和Visual Studio并没有太多的PS经验,我觉得这是奇怪的和意想不到的。我在想“对象应该在它停止执行后自动处理。” –

回答

2

TL;博士

  • 定时器实例在会话创建范围

    • 您是否在ISE运行你的脚本,
    • 以及引用它的任何变量是否在范围内。
  • 始终定时器处置(或至少将其禁用),以防止它从生成更多的事件。

  • 一般 - 尽管这是手头的问题的原因 - 要知道,运行在ISE 脚本含蓄点源,这样反复执行在运行相同的范围,从前面的变量值挥之不去,这可能会导致意想不到的行为。


你的代码永远不会部署的(或禁用)定时器,因此:

  • 保持活着整个会议,不管是不是一个变量引用它

  • 继续生成事件,

  • 但他们只有窗体正在显示

这说明你的症状:只要你展示的形式再次排队,原来事件触发瞬间

的解决方案是处置定时器的一旦它已经完成了它的任务和触发事件(一次):

Add-Type -AssemblyName System.Windows.Forms 

$Form = New-Object System.Windows.Forms.Form 
$Timer = New-Object System.Windows.Forms.Timer 

$Timer.Add_Tick({ 
    &{ 
    Write-Output "Here" 
    $Form.Close()} | Write-Host 
}) 

$Timer.Interval = 3000 
$Timer.Start() 
$result = $Form.ShowDialog() 
$Timer.Dispose() # IMPORTANT: Dispose of the timer so it won't generate more events. 

即使与上述的ISE的隐式采购行为,重复的调用此代码按预期工作。

1

我认为它与ISE中的变量如何在脚本结束后仍然在内存中有关。如果您将

$Timer.Stop() 

添加到脚本的最后一行,然后关闭并重新打开它将工作的ISE。

+0

运行'$ Timer.Stop()'是很好的建议,但行为与ISE无关。 – mklement0

相关问题