рдХреЙрдорди рд▓рд┐рд╕реНрдк рдХреА рд╕рдмрд╕реЗ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рдФрд░ рдЖрдХрд░реНрд╖рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЗрд╕рдХрд╛ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рднреА рдЕрдирд┐рд╡рд╛рд░реНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХрдорд╛рддреНрд░ рд╕рд╣реА рд╣реИ, рдФрд░ рдЗрд╕ рд╕рд░рд▓ рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдП:
рдХреЙрдорди рд▓рд┐рд╕реНрдк рдореЗрдВ "рдЕрдкрд╡рд╛рдж" (рдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╕реАрдПрд▓-рд╢рд░реНрддреЛрдВ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХреЗ рддрдВрддреНрд░ рдХреЛ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рддрдВрддреНрд░ рд╕реЗ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдпрд╣ рддрджрдиреБрд╕рд╛рд░, рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рдЕрд╕рд╛рдзрд╛рд░рдг (рдФрд░ рди рдХреЗрд╡рд▓ рдЕрд╕рд╛рдзрд╛рд░рдг) рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рдкреЙрдк рдЕрдк рдХрд░рддреЗ рд╣реИрдВред рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдЦреЛрдП рдмрд┐рдирд╛ рд╡реЗ рдХрд╣рд╛рдВ рдЙрддреНрдкрдиреНрди рд╣реБрдП, рдЬреЛ рд╡рд┐рдХрд╛рд╕ рдХреА рд╕реБрд╡рд┐рдзрд╛, рдбрд┐рдмрдЧрд┐рдВрдЧ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдЬрд┐рдХ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред
рд╕рдВрднрд╡рддрдГ, рдпрд╣ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕рд╛рдорд╛рдиреНрдп рд▓рд┐рд╕реНрдк рд╕реНрдерд┐рддрд┐ рдкреНрд░рдгрд╛рд▓реА, рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХрдИ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЬрд╛рдиреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЖрдзреБрдирд┐рдХ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдЯреВрд▓ рдХреЗ рдмрд╣реБрдд рдХрд░реАрдм рд╣реИ, рдЕрд░реНрдерд╛рддреН: рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдпреВрдирд┐рдХреНрд╕ рд╕рд┐рдЧреНрдирд▓ рдФрд░ рд╕рд┐рдЧреНрдирд▓, рдПрд╕рдИрдПрдЪ (рд╕рдВрд░рдЪрд┐рдд рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ) рддрдВрддреНрд░ рдХреЗ рдмрд╣реБрдд рдХрд░реАрдм рд╣реИред рдЦрд┐рдбрд╝рдХрд┐рдпреЛрдВ рд╕реЗред рд▓реАрдбрд┐рдВрдЧ рд╕реАрдПрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмреЗрд╕ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдлреНрд▓реЛ рдХрдВрдЯреНрд░реЛрд▓ рдЬреИрд╕реЗ рдХрд┐ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рдЙрди рдкрд░ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рдиред
рдХрдИ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕рдорд╛рди рддрдВрддреНрд░ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд╡рдЬреВрдж (рдпрджрд┐ рд╕рднреА рдирд╣реАрдВ), рддреЛ рдпрд╣ рдЙрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд░ рдХрдо рдпрд╛ рдЬреНрдпрд╛рджрд╛ рд╕рдВрдд рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЙрдзрд╛рд░ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдЕрдиреБрдЪреНрдЫреЗрдж рдореЗрдВ, рдореИрдВ рд╕реА # рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ, "рдЕрдкрд╡рд╛рджреЛрдВ" рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдмрд╣реБрдд рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд░рд╣рд╛ рд╣реВрдВред
рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╕реЗ CLCS рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╛ рдЗрд╕рдХреЗ рд░рдирдЯрд╛рдЗрдо рд╕реЗ рднреА, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:
- рд╕рдЦреНрдд рд╕реНрдЯреИрдХ рдореЙрдбрд▓ред рдпрд╣рд╛рдБ, рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рднрд╛рд╖рд╛ рдореЗрдВ рдкреВрд░реНрдг "рдирд┐рд░рдВрддрд░рддрд╛" рдХреА рдХрдореАред рдпрд╣ рдмрд┐рдВрджреБ рд╕рд╢рд░реНрдд рд╣реИ, рд▓реЗрдХрд┐рди рдЪреВрдБрдХрд┐ рдирд┐рд░рдВрддрд░рддрд╛, рд╕рдВрдЧрдгрдирд╛ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдирд┐рдпрдВрддреНрд░рдг рддрдВрддреНрд░ рдореЗрдВ рднрд╛рд░реА рдлрд╝рд┐рдЬрд╝рдиреЗрд╕ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреА рд╣реИ, рдФрд░ рд╡реЗ рдкрд░реНрдпрд╛рдкреНрдд рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдореВрд▓ рдкреНрд░рд╛рдЗрдореЗрдЯрд┐рдХреНрд╕ рдЬрд┐рдирд╕реЗ рд╕реАрдПрд▓рд╕реАрдПрд╕ рдХреЛ рдирд┐рд░рд╕реНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрдирдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдЕрддреНрдпрдВрдд рдЕрд╡рд╛рдВрдЫрдиреАрдп рд╣реИред
- рдЙрдЪреНрдЪ-рдХреНрд░рдо рдлрд╝рдВрдХреНрд╢рди, рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдХреНрд▓реЛрдЬрд╝рд░ред рдмреЗрд╢рдХ, рдпрджрд┐ рдЖрдк рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╡рд╕реНрддреБрдУрдВ рдФрд░ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдм рдХреБрдЫ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдЗрди рд╕рднреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдмрд╣реБрдд рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред
- рдЧрддрд┐рд╢реАрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдФрд░, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЧрддрд┐рд╢реАрд▓ рдЪрд░ред рдЧрддрд┐рд╢реАрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдФрд░ рдЪрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд▓реЗрдЦ рдореЗрдВ рдЖрдзреБрдирд┐рдХ рд▓рд┐рд╕реНрдк рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рд╡рд┐рд╡рд░рдг рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИ: love5an.livejournal.com/371169.html
рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: - рдХреЛрд╢рд┐рд╢, рдкрдХрдбрд╝, рдФрд░ рдмрдпрд╛рди, рдпрд╛ рдЙрдирдХреЗ рд╕рдордХрдХреНрд╖ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред рдпреЗ рдСрдкрд░реЗрдЯрд░ рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рд╣реИрдВ рдЬреЛ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред
- UNWIND-PROTECT рдЖрджрд┐рдо рдпрд╛ рдЙрд╕рдХреЗ рдЕрдиреБрд░реВрдк (рдХреЛрд╢рд┐рд╢ рдЕрдВрдд рдореЗрдВ рдмреНрд▓реЙрдХ, RAII, рдЖрджрд┐)ред
рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реАрдПрд▓ рдЕрдкрд╡рд╛рдж рдкреНрд░рдгрд╛рд▓реА рдЖрджрд┐рдорддрд╛ рдХреЛ C # рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд░реЗрдВрдЧреЗ:
- рд╣реИрдВрдбрд▓рд░-рдмрд╛рдЗрдВрдб - рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдмреЙрдбреА рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдкрд░, рд╣реИрдВрдбрд▓рд░ рд╕реНрдЯреИрдХ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
- рд╣реИрдВрдбрд▓рд░-рдХреЗрд╕ - рдСрдкрд░реЗрдЯрд░ рдмреЙрдбреА рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЬрдм рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдЯреИрдХ рдирд┐рд░рд╛рдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдСрдкрд░реЗрдЯрд░ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдорд╛рди рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред
- рд╕рдВрдХреЗрдд - рдПрдХ рдЙрдЪреНрдЪ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдЕрдЧрд░ рдХреЛрдИ рдореМрдЬреВрдж рд╣реИред
- рддреНрд░реБрдЯрд┐ - рдПрдХ рдЕрдкрд╕реНрдЯреНрд░реАрдо рд╣реИрдВрдбрд▓рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрднрд╛рд╡ рдореЗрдВ, рдпрд╛ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╣реИрдВрдбрд▓рд░ рдХреА рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ - рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдереНрд░реЛ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде (рдпрд╣ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣реИред рдХреЙрдорди рд▓рд┐рд╕реНрдк рдореЗрдВ, рддреНрд░реБрдЯрд┐ рдлрд╝рдВрдХреНрд╢рди рдбрд┐рдмрдЧрд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдХреЛрдИ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдпрд╛, рдЕрдиреНрдпрдерд╛, рдЧрдгрдирд╛ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рдзрд╛рдЧрд╛ рдпрд╛ рд╕рдВрдкреВрд░реНрдг рд▓рд┐рд╕реНрдк рд╕рд┐рд╕реНрдЯрдо рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред)
- рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ-рдмрд╛рдЗрдВрдб - рдПрдХ "рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ" рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдореИрдХреЗрдирд┐рдЬреНрдо рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдирд╛ рд╡рд░реНрддрдорд╛рди рдЧрддрд┐рд╢реАрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ (рдКрдкрд░ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рджреЗрдЦреЗрдВ) рдЬреЛ рдХрд┐рд╕реА рдЕрдкрд╡рд╛рдж рдХрд╛ рдЬрд╡рд╛рдм рджреЗ рд╕рдХрддрд╛ рд╣реИред рд░реЗрд╕реНрдЯрд╛рд░реНрдЯреНрд╕ рдХреЛ рдЖрдорддреМрд░ рдкрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рдХрд┐рд╕реА рддрд░рд╣ рд╣реБрдИ рддреНрд░реБрдЯрд┐ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡реЗ рдЖрдорддреМрд░ рдкрд░ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ (рдиреАрдЪреЗ рджреЗрдЦреЗрдВ)ред
- рдкреБрдирдГ рдЖрд░рдВрдн-рдорд╛рдорд▓рд╛ - "рдкреБрдирдГ рдЖрд░рдВрдн" рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рд╕реНрдЯреИрдХ рдХреЗ рдкреНрд░рдЪрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред
- рдкреБрдирдГ рдЖрд░рдВрдн - рдирд╛рдо рд╕реЗ "рдкреБрдирдГ рдЖрд░рдВрдн" рдвреВрдБрдврддрд╛ рд╣реИред
- рдЖрд╣реНрд╡рд╛рди-рдкреБрдирдГ рдЖрд░рдВрдн - рдирд╛рдо рд╕реЗ "рдкреБрдирдГ рдЖрд░рдВрдн" рдкрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред
- рдХрдВрдкреНрдпреВрдЯ-рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ - рд╡рд░реНрддрдорд╛рди рдбрд╛рдпрдирд╛рдорд┐рдХ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рд╕рднреА "рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ" рдХреА рд╕реВрдЪреА рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
- рдЦреЛрд▓рдирд╛-рд╕реБрд░рдХреНрд╖рд┐рдд рдХрд░рдирд╛ - рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╢рд░реАрд░ рдХреЗ рдПрдХ рдмреНрд▓реЙрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ - рднрд▓реЗ рд╣реА рдирд┐рд╖реНрдкрд╛рджрди рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреВрд░рд╛ рд╣реЛ, рдпрд╛ рд╕реНрдЯреИрдХ рдХреЗ рдЬрдмрд░рди рдкреНрд░рдЪрд╛рд░ рдХреЗ рдмрд╛рд╡рдЬреВрдж - рдпрд╣ рд╕рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ "рд╕реБрд░рдХреНрд╖рд╛" рдмреНрд▓реЙрдХ (рдлрд╝рдВрдХреНрд╢рди) рдХрд░рддрд╛ рд╣реИред
рдЖрдк рдЕрдзреНрдпрд╛рдп 19 рдореЗрдВ рдкреАрдЯрд░ рд╕рд┐рдмреЗрд▓ рдХреА рдЕрджреНрднреБрдд рдкреБрд╕реНрддрдХ рдкреНрд░реИрдХреНрдЯрд┐рдХрд▓ рдХреЙрдорди рд▓рд┐рд╕реНрдк рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЗрди рдФрд░ рдЕрдиреНрдп рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ:
lisper.ru/pcl/beyond-exception-handling-conditions-and-restartsрд╣рдорд╛рд░реЗ рд╕рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реНрдерд┐рд░ рд╡рд░реНрдЧ
рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реЛрдВрдЧреЗред рдЖрдЧреЗ, рдореИрдВ рдЙрдирдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдБрдЧрд╛ред
рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕реНрдерд┐рд░ рдЪрд░ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╖реНрдкрд╛рджрди рдереНрд░реЗрдб рдореЗрдВ, рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рджреМрд░рд╛рди рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдФрд░ рдкреБрдирд░рд╛рд░рдВрдн рдПрдХ рд╕реНрдЯреИрдХ рдмрдирд╛рддреЗ рд╣реИрдВред рдЖрдо рддреМрд░ рдкрд░ рдмреЛрд▓рдирд╛, рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдмреЛрд▓рдирд╛, рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХрд╛ рдЧрддрд┐рд╢реАрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рд╕реНрдЯреИрдХ рдмрдирд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╕реА # рдореЗрдВ рдХреЛрдИ рдЧрддрд┐рд╢реАрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдирд╣реАрдВ рд╣реИрдВ, рдХрдбрд╝рд╛рдИ рд╕реЗ рдмреЛрд▓ рд░рд╣реЗ рд╣реИрдВ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ "рд╕реНрдЯреИрдХ" рдХреЛ "рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ" рдЬреЛрдбрд╝реЗрдВрдЧреЗред
static ConditionalWeakTable<Thread, Stack<Tuple<Type, HandlerBindCallback>>> _handlerStacks; static ConditionalWeakTable<Thread, Stack<Tuple<string, RestartBindCallback>>> _restartStacks; static Conditions() { _handlerStacks = new ConditionalWeakTable<Thread, Stack<Tuple<Type, HandlerBindCallback>>>(); _restartStacks = new ConditionalWeakTable<Thread, Stack<Tuple<string, RestartBindCallback>>>(); }
"рдереНрд░реЗрдб -> рд╕реНрдЯреИрдХ" рдбрд┐рдХреНрд╢рдирд░реА рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ .NET 4.0 рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП ConditionalWeakTable рдХреНрд▓рд╛рд╕ рдХреЛ рдЪреБрдирд╛, рд▓реЗрдХрд┐рди рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рд╕рдорд╛рди рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред ConditionalWeakTable рдЕрдЪреНрдЫрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ "рдХрдордЬреЛрд░ рд╕рдВрдХреЗрдд" (WeakPointer - рдЗрд╕рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХреЗ рдирд╛рдо рдореЗрдВ рдХрдордЬреЛрд░ рд╣реИ) рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде рдПрдХ рд╣реИрд╢-рдкреНрд▓реЗрдЯ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЬрдм рдХрдЪрд░рд╛ рдХрд▓реЗрдХреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдереНрд░реЗрдб рдСрдмреНрдЬреЗрдХреНрдЯ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд▓реАрдХ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ рд╕реНрдореГрддрд┐ред
рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдФрд░ рд╕рд┐рдЧреНрдирд▓рд┐рдВрдЧ
HandlerBind
public static T HandlerBind<T>(Type exceptionType, HandlerBindCallback handler, HandlerBody<T> body) { if (null == exceptionType) throw new ArgumentNullException("exceptionType"); if (!exceptionType.IsSubclassOf(typeof(Exception))) throw new InvalidOperationException("exceptionType is not a subtype of System.Exception"); if (null == handler) throw new ArgumentNullException("handler"); if (null == body) throw new ArgumentNullException("body"); Thread currentThread = Thread.CurrentThread; var clusters = _handlerStacks.GetOrCreateValue(currentThread); clusters.Push(Tuple.Create(exceptionType, handler)); try { return body(); } finally { clusters.Pop(); } }
рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рд╡рд┐рдзрд┐ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддреА рд╣реИ: рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ рдЕрдкрд╡рд╛рдж рдХрд╛ рдкреНрд░рдХрд╛рд░ (рдЬреИрд╕рд╛ рдХрд┐ рд╡рд┐рдзрд┐ рдХреЗ рд╢рд░реАрд░ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдЕрдкрд╡рд╛рдж рдХрд╛ рдПрдХ рдЙрдк-рд╡рд░реНрдЧ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП), рдПрдХ рдХреЙрд▓рдмреИрдХ рдЬреЛ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХреЛрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдЕрдиреНрдп рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдЬреЛ рдХреЛрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХрдерди рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдкреНрд░рдХрд╛рд░ рд╣реИрдВрдбрд▓рд░ рдФрд░ рдмреЙрдбреА рд╣реИрдВ:
public delegate void HandlerBindCallback(Exception exception); public delegate T HandlerBody<T>();
рд╣реИрдВрдбрд▓рд░ рдХреЗ рдкрд╛рд╕ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЕрдкрд╡рд╛рдж рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдкрд╡рд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реА рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд░рд▓ рд╣реИ - рд╣рдо рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХреЗ рдвреЗрд░ рдореЗрдВ рдПрдХ рдирдпрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЙрд╕рдХреЗ рдмрд╛рдж рд╣рдо рдСрдкрд░реЗрдЯрд░ рдмреЙрдбреА рдХреЗ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЖрдЦрд┐рд░рдХрд╛рд░ рдмреЙрдбреА рдореЗрдВ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕реНрдЯреИрдХ рд╕реЗ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдХрд╛ рд╕реНрдЯреИрдХ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдФрд░ рдЬрдм рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╖реНрдкрд╛рджрди рдереНрд░реЗрдб рдЗрд╕реА рд╕реНрдЯреИрдХ рдлрд╝реНрд░реЗрдо рдХреЛ рдЫреЛрдбрд╝рддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд╛рдкрд┐рдд рд╣реИрдВрдбрд▓рд░ рдЕрдорд╛рдиреНрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
HandlerCase
public static T HandlerCase<T>(Type exceptionType, HandlerCaseCallback<T> handler, HandlerBody<T> body) { if (null == exceptionType) throw new ArgumentNullException("exceptionType"); if (!exceptionType.IsSubclassOf(typeof(Exception))) throw new InvalidOperationException("exceptionType is not a subtype of System.Exception"); if (null == handler) throw new ArgumentNullException("handler"); if (null == body) throw new ArgumentNullException("body"); var unwindTag = new UnwindTag<T>(); HandlerBindCallback handlerCallback = (e) => { unwindTag.Value = handler(e); throw unwindTag; }; try { return HandlerBind(exceptionType, handlerCallback, body); } catch (UnwindTag<T> e) { if (e == unwindTag) { return e.Value; } else throw; } }
рд╣реИрдВрдбрд▓рд░рдХреИрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рд╕реЗ рдЕрдВрддрд░, рдореБрдЭреЗ рдпрд╛рдж рд╣реИ, рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдСрдкрд░реЗрдЯрд░ рдЙрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрдкрд┐рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╣реИрдВрдбрд▓рд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реИред рдЪреВрдБрдХрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рднрд╛рдЧрдиреЗ рдХреА рдирд┐рд░рдВрддрд░рддрд╛ C # рдореЗрдВ рдирд┐рд╖рд┐рджреНрдз рд╣реИ (рдЕрд░реНрдерд╛рдд рдореЛрдЯреЗ рддреМрд░ рдкрд░, рд╣рдо рдЧреЛрдЯреЛ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рд╕реЗ рд╡рд╛рдкрд╕ рд▓реМрдЯрдиреЗ рдкрд░ рд╕реНрдЯреИрдХ рдХреЛ рдПрдХ рдмрд╛рд╣рд░реА рдмреНрд▓реЙрдХ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рд╣рдо рд╕реНрдЯреИрдХ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рдмреНрд▓реЙрдХ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рддреЗ рд╣реИрдВ рд╕рд╣рд╛рдпрдХ рд╡рд░реНрдЧ
UnwindTag рдХреА рдПрдХ рд╡рд╕реНрддреБ
class UnwindTag<T> : Exception { public T Value { get; set; } }
рд╣реИрдВрдбрд▓рд░рдХреИрд╕рд▓рдмреИрдХ рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдбрдмреИрдХ рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ рдХреЗрд╡рд▓ рдЙрд╕реА рдореЗрдВ рдпрд╣ рдорд╛рди рджреЗрддрд╛ рд╣реИ:
public delegate T HandlerCaseCallback<T>(Exception exception);
рд╕рдВрдХреЗрдд
рд╕рд┐рдЧреНрдирд▓ рдлрд╝рдВрдХреНрд╢рди рд╕реАрдПрд▓ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдмрд╣реБрдд рджрд┐рд▓ рдореЗрдВ рд╣реИред рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдереНрд░реЛ рдФрд░ рдХреЙрдорд░реЗрдбреНрд╕ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдХреЙрд▓ рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрдкрд┐рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рдЕрдкрд╡рд╛рдж рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╣реБрдЖ рд╣реИ, рдЕрд░реНрдерд╛рдд рдпрд╣ рдмрд╕ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
public static void Signal<T>(T exception) where T : Exception { if (null == exception) throw new ArgumentNullException("exception"); Thread currentThread = Thread.CurrentThread; var clusters = _handlerStacks.GetOrCreateValue(currentThread); var i = clusters.GetEnumerator(); while (i.MoveNext()) { var type = i.Current.Item1; var handler = i.Current.Item2; if (type.IsInstanceOfType(exception)) { handler(exception); break; } } }
рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░ - рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЕрдкрд╡рд╛рдж рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЗ рд╡рд░реНрддрдорд╛рди рдвреЗрд░ рд╕реЗ, рд╣рдо рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЛ рдЕрдкрд╡рд╛рдж рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЕрдкрд╡рд╛рдж рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╛рд░рд┐рдд рд╡рд╕реНрддреБ рд╣реИред
рддреНрд░реБрдЯрд┐
public static void Error<T>(T exception) where T : Exception { Signal(exception); throw exception; }
рддреНрд░реБрдЯрд┐ рдХреЗрд╡рд▓ рд╕рд┐рдЧреНрдирд▓ рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВрдбрд▓рд░ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рддреА рд╣реИред рдЕрдЧрд░ рд╣рдо "рдлреЗрдВрдХ рдЕрдкрд╡рд╛рдж" рдХреЗ рдмрдЬрд╛рдп .NET рдХреЗ рддрд╣рдд рдЖрдо рд▓рд┐рд╕реНрдк рдХрд╛ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рддреЛ "InvokeDebuggerOrDie (рдЕрдкрд╡рд╛рдж)" рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реЛрдЧрд╛;
рдкреБрдирд░рд╛рд░рдВрдн
RestartBind рдФрд░ RestartCase
RestartBind рдФрд░ RestartCase, HandlerBind рдФрд░ HandlerCase рдХреЗ рд╕рдорд╛рди рд╣реИрдВ, рдЗрд╕ рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде рдХрд┐ рд╡реЗ рд░реАрд╕реНрдЯреИрдХ рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддрд┐рдирд┐рдзрд┐-рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЕрдкрд╡рд╛рдж рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ рдирд╛рдо рдХреЛ рдореИрдк рдХрд░рддреЗ рд╣реИрдВред
public delegate object RestartBindCallback(object param); public delegate T RestartCaseCallback<T>(object param); public static T RestartBind<T>(string name, RestartBindCallback restart, HandlerBody<T> body) { if (null == name) throw new ArgumentNullException("name"); if (null == restart) throw new ArgumentNullException("restart"); if (null == body) throw new ArgumentNullException("body"); Thread currentThread = Thread.CurrentThread; var clusters = _restartStacks.GetOrCreateValue(currentThread); clusters.Push(Tuple.Create(name, restart)); try { return body(); } finally { clusters.Pop(); } } public static T RestartCase<T>(string name, RestartCaseCallback<T> restart, HandlerBody<T> body) { if (null == name) throw new ArgumentNullException("name"); if (null == restart) throw new ArgumentNullException("restart"); if (null == body) throw new ArgumentNullException("body"); var unwindTag = new UnwindTag<T>(); RestartBindCallback restartCallback = (param) => { unwindTag.Value = restart(param); throw unwindTag; }; try { return RestartBind(name, restartCallback, body); } catch (UnwindTag<T> e) { if (e == unwindTag) { return e.Value; } else throw; } }
FindRestart рдФрд░ InvokeRestart
FindRestart рдФрд░ InvokeRestart, рдмрджрд▓реЗ рдореЗрдВ, рд╕рд┐рдЧреНрдирд▓ рд╡рд┐рдзрд┐ рдХреЗ рд╕рдорд╛рди рд╣реИрдВ - рдкрд╣рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕реНрдЯреИрдХ рдореЗрдВ рдирд╛рдо рд╕реЗ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рди рдХреЗрд╡рд▓ рдЗрд╕реЗ рдвреВрдВрдврддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рддреБрд░рдВрдд рдЗрд╕реЗ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред
public static RestartBindCallback FindRestart(string name, bool throwOnError) { if (null == name) throw new ArgumentNullException("name"); Thread currentThread = Thread.CurrentThread; var clusters = _restartStacks.GetOrCreateValue(currentThread); var i = clusters.GetEnumerator(); while (i.MoveNext()) { var restartName = i.Current.Item1; var restart = i.Current.Item2; if (name == restartName) return restart; } if (throwOnError) throw new RestartNotFoundException(name); else return null; } public static object InvokeRestart(string name, object param) { var restart = FindRestart(name, true); return restart(param); }
ComputeRestarts
ComputeRestarts рдмрд╕ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рд╕рднреА рдкреБрдирд░рд╛рд░рдВрднреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ - рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП рддрд╛рдХрд┐, рдЬрдм рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдП, рдпрд╣ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреБрдХреНрдд рдкреБрдирд░рд╛рд░рдВрдн рдЪреБрди рд╕рдХрддрд╛ рд╣реИред
public static IEnumerable<Tuple<string, RestartBindCallback>> ComputeRestarts() { var restarts = new Dictionary<string, RestartBindCallback>(); Thread currentThread = Thread.CurrentThread; var clusters = _restartStacks.GetOrCreateValue(currentThread); return clusters.AsEnumerable(); }
UnwindProtect
рдЕрдирд╡рд┐рдВрдбрдкреНрд░реЛрдЯреЗрдХреНрдЯ рдХрд╛ рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрд╕ рдПрдХ рдХреЛрд╢рд┐рд╢-рдЖрдЦрд┐рд░ рдмреНрд▓реЙрдХ рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИред
public static T UnwindProtect<T>(HandlerBody<T> body, params Action[] actions) { if (null == body) throw new ArgumentNullException("body"); if (null == actions) actions = new Action[0]; try { return body(); } finally { foreach (var a in actions) a(); } }
рдЕрдВрдд рдореЗрдВ, рдЙрдкрдпреЛрдЧ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдгред
- рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдЬреЛ рдЕрдкрд╡рд╛рдж рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИред
static int DivSignal(int x, int y) { if (0 == y) { Conditions.Signal(new DivideByZeroException()); return 0; } else return x / y; }
int r = Conditions.HandlerBind( typeof(DivideByZeroException), (e) => { Console.WriteLine("Entering handler callback"); }, () => { Console.WriteLine("Entering HandlerBind with DivSignal"); var rv = DivSignal(123, 0); Console.WriteLine("Returning {0} from body", rv); return rv; }); Console.WriteLine("Return value: {0}\n", r);
рдпрд╣рд╛рдБ DivSignal рдлрд╝рдВрдХреНрд╢рди, рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рдПрдХ рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рд╕рд╛рде, рдПрдХ рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ рдЬреЛ рдЙрддреНрдкрдиреНрди рд╣реБрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдпрд╣ рдЗрд╕рдХреЗ рд╕рд╛рде "рд╕рд╛рдордирд╛" рдХрд░рддрд╛ рд╣реИ (рд╢реВрдиреНрдп рд▓реМрдЯрддрд╛ рд╣реИ)ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рди рддреЛ рд╣реИрдВрдбрд▓рд░ рдФрд░ рди рд╣реА рдлрд╝рдВрдХреНрд╢рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред
рдХрдВрд╕реЛрд▓ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
Entering HandlerBind with DivSignal Entering handler callback Returning 0 from body Return value: 0
- рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреНрд░реБрдЯрд┐ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╣реИрдВрдбрд▓рд░рдХреИрд╕ рдФрд░ рдЕрдирд╡рд┐рдВрдбрдкреНрд░реЛрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред
static int DivError(int x, int y) { if (0 == y) Conditions.Error(new DivideByZeroException()); return x / y; }
int r = Conditions.HandlerCase( typeof(DivideByZeroException), (e) => { Console.WriteLine("Entering handler callback"); Console.WriteLine("Returning 0 from handler"); return 0; }, () => { Console.WriteLine("Entering HandlerCase with DivError and UnwindProtect"); return Conditions.UnwindProtect( () => { Console.WriteLine("Entering UnwindProtect"); var rv = DivError(123, 0); Console.WriteLine("This line should not be printed"); return rv; }, () => { Console.WriteLine("UnwindProtect exit point"); }); }); Console.WriteLine("Return value: {0}\n", r);
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, DivError рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣реИрдВрдбрд▓рд░ рдЗрд╕реЗ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрдкрд┐рди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, 0)ред рдЬреИрд╕рд╛ рдХрд┐ рд╕реНрдЯреИрдХ рдЕрдирдбрд┐рдВрдб рдХрд░рддрд╛ рд╣реИ, рдЧрдгрдирд╛ рдкреНрд░рд╡рд╛рд╣ рдЕрдирд╡рд┐рдВрдбрдкреНрд░реЛрдЯреЗрдХреНрдЯ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИред
рдпрд╣ рдЙрджрд╛рд╣рд░рдг, рджреВрд╕рд░реЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдореЗрд╢рд╛ рдХреА рдХреЛрд╢рд┐рд╢, рдкрдХрдбрд╝рдиреЗ рдФрд░ рдЕрдВрдд рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХрдВрд╕реЛрд▓ рдЖрдЙрдЯрдкреБрдЯ:
Entering HandlerCase with DivError and UnwindProtect Entering UnwindProtect Entering handler callback Returning 0 from handler UnwindProtect exit point Return value: 0
- рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреБрдирд░рд╛рд░рдВрдн рд╕реНрдерд╛рдкрд┐рдд рд╣реИред
static int DivRestart(int x, int y) { return Conditions.RestartCase( "ReturnValue", (param) => { Console.WriteLine("Entering restart ReturnValue"); Console.WriteLine("Returning {0} from restart", param); return (int)param; }, () => { Console.WriteLine("Entering RestartCase"); return DivError(x, y); }); }
DivRestart рдиреЗ тАЬReturnValueтАЭ рдирд╛рдордХ рдПрдХ рдкреБрдирд░рд╛рд░рдВрдн рдХреЛ рд╕реЗрдЯ рдХрд┐рдпрд╛, рдЬреЛ рд╕рдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдкрд░, рдмрд╕ (рдкреИрд░рд╛) рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕реЗ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдорд╛рди рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред RestartCase рдХрд╛ рд╢рд░реАрд░ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╡рд░реНрдгрд┐рдд DivError рдХреЛ рдЙрдард╛рддрд╛ рд╣реИред
int r = Conditions.HandlerBind( typeof(DivideByZeroException), (e) => { Console.WriteLine("Entering handler callback"); Console.WriteLine("Invoking restart ReturnValue with param = 0"); Conditions.InvokeRestart("ReturnValue", 0); }, () => { Console.WriteLine("Entering HandlerBind with DivRestart"); return DivRestart(123, 0); }); Console.WriteLine("Return value: {0}", r);
рд╣реИрдВрдбрд▓рд░рдмрд╛рдЗрдВрдб рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рд╣реИрдВрдбрд▓рд░, рдЬрд┐рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ "рд░рд┐рдЯрд░реНрдирд╡реИрд▓реНрдпреВ" рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирдВрдмрд░ 0 рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдмрд╛рдж "рд░рд┐рдЯрд░реНрдирд╡реИрд▓реНрдпреВ" рд╕рдХреНрд░рд┐рдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рд╕реНрдЯреИрдХ рдХреЛ рдЙрд╕рдХреЗ рд╕реНрддрд░ рддрдХ рдлреИрд▓рд╛ рджреЗрддрд╛ рд╣реИ, рдФрд░ DivRestart рдореЗрдВ рд╕реЗрдЯ рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯрдХреИрд╕реЗ рд╕реЗ рдЙрд╕реА рдирдВрдмрд░ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖:
Entering HandlerBind with DivRestart Entering RestartCase Entering handler callback Invoking restart ReturnValue with param = 0 Entering restart ReturnValue Returning 0 from restart Return value: 0
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдкреВрд░рд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ рдЙрджрд╛рд╣рд░рдг github:
github.com/Lovesan/ConditionSystem рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ