梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
´´´´´´´´´´´´´´´´´´´´´´Page 146´´´´´´´´´´´´´´´´´´´´´´´
124 CH AP T E R 5 * L E A R N IN G AB OU T V I SU A L B AS IC E X C E P TI ON H AN D L IN G
Figure 5´6。 Unwinding the stack can cause a method call to be skipped。
In the example in Figure 5´6�察�the methods are called sequentially�察�starting with RunAll�┌��察 �
and then when a single exception is thrown�察�the code in the RunAll�┌� method¨s Catch block is
executed immediately。 So�察�depth has a value of 2 instead of a value of 0 ��the value you would
expect if no exception were thrown�� when execution finishes。 You can see that the stack has
unwound too fast�察�leaving the program with unpredictable results。
The stack unwinding problem causes corruption and can wreak havoc on your program。
A seemingly working program might corrupt itself and slowly fail or generate incorrect data。
Fortunately�察�there are a couple ways to handle stack unwinding correctly。
Using Finally to Process Unfinished Tasks
The simplest solution to the stack unwinding problem is to use the Finally keyword�察�which
indicates that you want to guarantee a piece of code executes�察�whether or not an exception is
thrown。 The following shows how you could rewrite the example in Figure 5´6 using Finally。
When executed�察�this code will set the depth data member to the correct value。
Class CallingExample
Dim depth As Integer
Public Sub CalledCalledMethod�┌�
Me。depth = 2
Throw New Exception�┌�
End Sub
´´´´´´´´´´´´´´´´´´´´´´Page 147´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 5 * L E AR N IN G AB O U T V I SU A L B AS IC E X CE PT I ON HA N D L IN G 125
Public Sub CalledMethod�┌�
Me。depth = 1
Try
CalledCalledMethod�┌�
Finally
Me。depth = 1
End Try
End Sub
Public Sub Method�┌�
Me。depth = 0
Try
CalledMethod�┌�
Finally
Me。depth = 0
End Try
End Sub
Public Function GetDepth�┌� As Integer
Return Me。depth
End Function
End Class
Class Tests
Sub TestCallingExample�┌�
Dim cls As CallingExample = Nothing
Try
cls = new CallingExample�┌�
cls。Method�┌�
Catch exception1 As Exception
End Try
Console。WriteLine�─�Depth is �──�& cls。GetDepth�┌� & ;��;��
End Sub
Public Sub RunAll�┌�
TestCallingExample�┌�
End Sub
End Class
In this example�察�each Finally keyword is associated with a Try block。 You don¨t need to
associate a Catch block with a Try block if you are using Finally。 If the Try block is entered�察 �
when the code leaves the Try block�察�regardless of whether it ran successfully or threw an excep
tion�察�the code within Finally is executed。 Thus�察�if stack unwinding occurs�察�it is possible to reset
or assign state to a consistent value before the exception is processed elsewhere。
*Note When the Finally block is called�察�you don¨t know if it is called due to an exception or successful
code execution。 Thus�察�you shouldn¨t assume that Finally is called because an exception was thrown。
´´´´´´´´´´´´´´´´´´´´´´Page 148´´´´´´´´´´´´´´´´´´´´´´´
126 CH AP T E R 5 * L E A R N IN G AB OU T V I SU A L B AS IC E X C E P TI ON H AN D L IN G
Sandboxing Your Code
The sandboxing technique is similar to playing with an Etch A Sketch�察�in that you attempt to
build a state�察�and if you make a mistake�察�you can throw the state away。 This requires that you
separate your code into three distinct steps�此�declaration�察�manipulation�察�and integration。 Figure 5´7
illustrates the three steps in sandboxing your code。
1。 Declaration�此�Each variable is
declared and assigned a default state
Function Separated�┌� As SeparateSteps that will not generate an exception
Dim cls As SeparateSteps = Nothing
cls = New SeparateSteps�┌� 2。 Manipulation�此�Each variable is manipulated
cls。PossibleExceptionMethod�┌�
using methods to create a state that does not
Return cls alter anything outside the method。 The variables
End Function may reference the global state�察�but not change it。
3。 Integration�此�Once the state has
been modified�察�an integration into the
bigger system can occur
Figure 5´7。 Sandboxing your code
Figure 5´7 illustrates one way of performing a sandboxing operation�察�but there are many
other possible implementations。 In each of the different implementations�察�the objective is the
same�此�you want to perform the operations that could cause an exception apart from the main
code。 Then if you do have an exception�察�it will be localized to the separate code。 When the stack
unwinds�察�the other code won¨t be corrupted。
*Note The rule of thumb with sandboxing your code is to keep all of the code manipulations that could
generate an exception separate from any existing state that could be corrupted。 Once the manipulations have
been carried ou