15.5.3 语义

可执行节点

活动中的可执行节点执行活动的一个实质性的行为步骤。可执行节点的所有流入和流出活动边都应为控制流。可执行节点可能消费和产生数据,但是这必须通过相关的对象节点来完成(Actions使用Pins来达到此目的;参见第16章)。

只有可执行节点的所有流入控制边都提交tokens它才能够执行。也就是说,在流入控制流上有一个隐含的join。特定类型的可执行节点可能还有其它的前提要满足才能开始执行。

在可执行节点开始执行前,它接受流入控制边上所有的tokens。如果一条控制流上提交了多个tokens,那么它们都被消费掉。从控制流接受对象tokens的效果没有规定(参见15.4中对象节点的isControlType),但是如果这个效果是执行该可执行节点,那么上面的语义就适用。

在可执行节点执行时,它被认为持有一个单一的控制(token)以指示它在运行。有些情况下,一个可执行节点的多个并发执行可能同时在进行(参见16.2中动作的isLocallyReentrant=true的语义)。此时,对于每个并发执行该可执行节点都持有一个控制token。

当一个可执行节点执行结束时,代表执行的控制token从该可执行节点移除被提交给它所有流出的控制流。也就是说,从可执行节点到它的流出控制边有一个隐含的fork。

异常和异常处理器

异常时一个值,用于指示执行的一个非正常结束方式(mode)。如果在可执行节点的执行中产生了一个异常(例如,使用RaiseExceptionAction;参见16.13)并且没有在该执行中处理,那么该执行执行终止并且异常从可执行节点传播出来。

一个可执行节点可以有一个或多个ExceptionHandlers(异常处理器),用于处理从可执行节点传播处理的异常,传播异常的可执行节点称为那些处理器(handlers)的受保护节点(protectedNode)。如果一个异常从受控节点传播处理,那么检查处理器选择与异常匹配的一个。如果异常的类型与处理器的异常类型(exceptionTypes)其中之一相同或者是它的子类,那么该处理器与异常匹配。如果有一个匹配,那么该处理器捕获这个异常。如果有多个匹配,只能一个处理器捕获异常,但没有定义是哪一个。

如果异常处理器捕获了异常,该异常被封装到一个对象token中并放置于该处理器的exceptionInput对象节点。然而异常处理器的handlerBody执行,它的执行可能会通过exceptionInput节点来访问被捕获的异常。

当异常处理器的handlerBody执行结束后,控制token移交给受保护节点的流出控制流,如图受保护节点正常结束一样。如果受保护节点是一个带有OutputPins的动作,那么handlerBody也必须是一个带有匹配OutputPins的动作,并且任何被置于此的tokens都会传送给受保护节点的OutputPins(参见16.2中的动作和Pins)。

handlerBody不应有流入或流出的活动边。充当一个handlerBody的可执行节点只有在它的handler捕获到一个异常时它才能对象进行响应和执行。

异常处理器的handlerBody应该与该异常处理器的受保护节点具有相同的宿主,并且它拥有异常处理器的exceptionInputexceptionInput应该无类型或者具有与该异常处理器的exceptionType相同或者是其泛化的类型。典型的,handlerBody会是一个结构化活动节点并且exceptionInput是它的一个InputPin(参见16.11中的结构化活动节点)。

如果可执行节点传播了一个异常而该节点没有handlers,或者没有与所传播异常匹配的handler,那么异常继续向外传播。如果在整个活动中该异常都没有被捕获,那么活动执行终止,异常传播到活动外。如果该活动是同步调用的,那么异常传播到调用者。如果活动是异步调用的,那么异常丢失且不再继续传播。

results matching ""

    No results matching ""