我认为您遇到的问题是粒子分析正在(至少部分)在单独的后台线程上运行。
我不相信在这种情况下有办法直接捕获这些异常。
我不再使用 GMS 1.84,但我确实在 GMS 3.2 上进行了尝试,您可能也想这样做以更好地了解正在发生的情况。
首先,您的 Try/Catch 循环是可以的,但是如果您不在 catch 中放置“break”,那么一旦离开 catch 部分,异常仍然会被提升到系统,即您经常想做的事情:
Try{
... }
Catch{
...
break
}
...
为了测试脚本对被调用方法的异常的行为方式,我首先编写了一个小脚本并将其“安装”为菜单命令,一次使用后台线程,一次不使用后台线程。我通过文件菜单安装了它们Custom带有命令名称的菜单BT and nBT, 分别:
// $BACKGROUND$
Result( "\nStart and wait" )
number i = 0
while( i < 100 ){
i++
sleep(0.05)
if ( ShiftDown() ) break
if ( OptionDown() ) Throw("Broken")
Result( "." )
}
Result("\nDone and exit.")
and
Result( "\nStart and wait" )
number i = 0
while( i < 100 ){
i++
sleep(0.05)
if ( ShiftDown() ) break
if ( OptionDown() ) Throw("Broken")
Result( "." )
}
Result("\nDone and exit.")
然后我使用“ChooseMenuItem()”在以下脚本中进行测试:
string name = TwoButtonDialog("Background threaded?", "yes", "no" ) ? "BT" : "nBT"
number success = 0
Try{
Result( "\n Calling: " + name )
success = ChooseMenuItem("Custom","",name)
}
catch
{
Result("\n Caught exception." )
break
}
result("\n Success: " + success )
使用此组合进行测试(并使用 ALT 键在例程中引发异常)我可以验证命令的行为正如预期的那样:
- 如果例程由
ChooseMenuItem
命令是在主线程上启动,然后该调用的执行将“阻止”主脚本,直到完成 - 无论是在结束时,还是在抛出异常时。主脚本正确捕获异常并打印结果。
- 如果例程由
ChooseMenuItem
命令是在单独的(后台)线程上启动,然后主脚本立即继续。ChooseMenuItem
立即成功返回(如果可以启动命令),并退出 Try/Catch 循环。后台线程上被调用例程抛出的任何异常将不再被捕获。
至于错误的根源:“无效索引”消息指向主脚本删除(或保留在范围内)的某个对象,该对象预计被调用的后台例程存在(或不再存在)。这可以是图像或图像文档或图像或图像显示器上的任何对象(ROI、掩模...)的显示。
我怀疑你的主要脚本正在做一些事情,比如关闭使用过的图像?如果“分析”是在单独的线程上进行的,那么您的主脚本可能会太快或太慢,从而导致事情不同步。您可能需要添加人为暂停(sleep()
)和更复杂的图像跟踪系统(使用图像ID)在主脚本中以避免此类事情。
Using ChooseMenuItem()
是一种变通的黑客解决方案,因此任何针对您的问题的错误预防解决方案也可能是需要一些丑陋的“创造力”的代码黑客。