Smalltalk支持使用on:retry方法重试异常,定义重试之间的行为.我想实现由两个附加操作组成的重试行为:delayInterval,maxAttempts
[ operations ]
on: Exception
maxAttempts: 10
delayInterval: 5 seconds
do: [ : e | Transcript show: 'Trying...'; cr ]
Run Code Online (Sandbox Code Playgroud)
有没有优雅的方法来做到这一点?
卡洛斯的做法很好,但我看到的问题是#on:do:多次发送消息.由于Exceptions了解#retry消息这一点,这不是必需的.因此,我们可以在处理块内部循环,而不是将所有内容都包含在循环中,如下所示:
BlockClosure >> on: aClass do: aBlock maxAttempts: anInteger
| counter |
counter := anInteger.
^self
on: aClass
do: [:ex | | result |
result := aBlock value: ex.
counter := counter - 1.
counter > 0 ifTrue:[ex retry].
ex return: result]
Run Code Online (Sandbox Code Playgroud)
请注意,此代码中没有"语法"循环.然而,执行流程将根据ex retry消息再次评估接收块(不到达ex return: result线路).只有counter到达0处理程序将"放弃"并返回异常块的值aBlock.
现在可以使用同样的想法来引入超时:
on: aClass
do: aBlock
maxAttempts: anInteger
timeout: anotherInteger
| counter timeout |
counter := anInteger.
timeout := TimeStamp now asMilliseconds + anotherInteger "dialect dependent".
^self
on: aClass
do: [:ex | | result |
result := aBlock value: ex.
counter := counter - 1.
(counter > 0 and: [TimeStamp now asMilliseconds < timeout])
ifTrue: [ex retry].
ex return: result]
Run Code Online (Sandbox Code Playgroud)
同样的考虑适用于此.唯一的区别是该retry条件还考虑了超时限制.
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |