Exception Handling 异常处理
With Photon 3.0 the exception handling went through a complete redesign. In previous versions the strategy was to catch all exceptions inside the Photon Framework (photonsocketserver.dll) and log them through a logging facade. This design had several drawbacks:
Photon3的异常处理进行了完整的重新设计。在旧版中,策略是内部捕获所有异常的Photon框架和通过日志记录他们。这样的设计有以下的缺陷:
- unhandled exception event handler not being called: The expected CLR default behavior is when exceptions are not handled by the developers code to be notified on the unhandled exception event handler.
- 未处理的异常事件不被调用
- exception handling dependency on logging: Developers had to implement a logging facade, failing to do so could lead to “lost” exceptions.
- 异常处理依赖于日志
- only one behavior for not handled exceptions: Exceptions not handled by the developer where caught by photon, logged and then ignored. Effectively working in a similar way the “runtime backstop” in .Net 1.x did.
- 有一种行为是不处理异常的
- inconsistent behavior: Unhandled exceptions in threads controlled by the developer raised the unhandled exceptions handler and terminated the process
- 不一致的行为
Content 目录
- New With Photon 3.0 新的
- Suggestions For the Usage Of the UnhandledExceptionPolicies 推荐使用UnhandledExceptionPolicies
- Logging Unhandled Exceptions 记录未处理的异常
- Configuring the UnhandledException Policy 配置未处理异常的策略
- Photon Core Debugging Photon核心调试
New With Photon 3.0: 新的
- unhandled exception event handler is always called: Exceptions not handled by the developers code will always raise the unhandled exception event handler.
- 未处理的异常事件总是被调用
- non-intrusive logging: We encourage developers to implement the unhandled exceptions handler, but independently of the developers code unhandled exceptions are logged by photon. For details see “Logging” section below.
- 非侵入性的日志记录
- three policies for unhandled exceptions: Photon supports one of three policies when an unhandled exception is raised - ignore, restart application, end process
- 三种针对未处理异常的策略
- consistent behavior
- 一致的行为
有2种情况异常的出来策略是继承于CLR,
ThreadAbortException 不必要的重启或停止进程,
StackOverflowException 不能被忽略的。
Note: the Application Compatibility Flag (legacyUnhandledExceptionPolicy) described in
Exceptions in Managed Threads
isn't supported by Photon on a per application config. This mode is set per instance (UnhandledExceptionPolicy = "Ignore") - see "Configuring the UnhandledException Policy" section below.
Suggestions For the Usage Of the UnhandledExceptionPolicies 推荐使用UnhandledExceptionPolicies
Microsoft introduced the “Terminate Process” as new default policy with .Net 2.0 with following statement quoted from
Exceptions in Managed Threads
:When threads are allowed to fail silently, without terminating the application, serious programming problems can go undetected. This is a particular problem for services and other applications which run for extended periods. As threads fail, program state gradually becomes corrupted. Application performance may degrade, or the application might hang.
微软推荐“Terminate Process” (终止进程)作为新的默认策略:当线程是允许静默失败,没有终止应用程序,严重的编程问题可以不被发现。这是一个特定的问题和其他应用程序的服务。因为线程失败,程序状态逐渐成为损坏的。应用程序的性能可能会降低,或应用程序可能挂起。
Allowing unhandled exceptions in threads to proceed naturally, until the operating system terminates the program, exposes such problems during development and testing. Error reports on program terminations support debugging.
允许未处理的异常在线程中继续,直到操作系统终止该问题,暴露此类的问题在开发和测试中。错误报告在程序终止时支持调试。
But depending on the stage or situation your project is (in development, in QA, LIVE without known issues, etc.) you might consider using one of the different policies supported by Photon:
但这取决于你项目的阶段或情况(在开发中,,在QA没有已知的问题,等等),你可能会考虑使用不同的Photon支持的策略:
- Restart Application 重启应用程序
- Ignore 忽略
- Terminate Process 终止进程
While developing setting “
Terminate Process” launches the debugger/visual studio on process termination. Are you handling with a multithreaded issue you might prefer to keep the process running and the application loaded then setting the policy “
Ignore” would be what you prefer.
虽然开发中设置“ 终止进程 “会在进程终止时启动visual studio调试器。你处理一个多线程问题,你可能倾向于保持进程运行和应用程序加载,然后你可能喜欢设置策略为” 忽略 “。
During a QA Phase, either during the run of stress tests or manual testing, using “
Terminate Process” ensures you won’t get flooded by errors that stem from the root-error.
在QA阶段,要么压力测试,要么手动运行测试,使用” 终止进程 “确保你不会被洪水淹没,错误源自根误差。
Live Stable - assuming your service is stable a policy you can consider using is the “
Restart Application”. In the rare event of an unhandled exception the application would be restarted by Photon minimizing the risks - this is the fastest way for the system to be up again. Faster than setup Photon as a Service with
“Terminate Process”
as policy and the auto-restart windows services feature. Note: you should monitor your service and log files in case this happens more often.
稳定——假设你的服务是稳定的一个策略,可以考虑使用“ 重启应用程序 “。在罕见的事件未处理的异常中会通过Photon重新启动应用程序来减少风险——这是最快的使系统重新运行的方法。快速的设置Photon为 “终止进程” 策略和自动重启Windows服务。注意:你应该监视你的服务和日志文件以防这种情况经常发生。
Live with a known issue - if the system shows an unexpected exception quite often and you need time to fix - depending on the exception it might be possible to keep a reasonably stable system by setting the policy to “
Ignore”.
一个已知的问题——如果系统显示一个未处理异常,通常你需要时间来修复——根据异常,保持一个合理稳定的系统可能需要设置策略为“ 忽略 “。
Note on
StackOverflows: Usually the stacktrace logged during the unhandled exception will point you to the fix. The
StackOverflowException
is a case where the stacktrace can get lost if the unhandled exception policy is set to “
Ignore” or “
RestartApplication”.
注意
StackOverflows:通常情况下,在未处理的异常堆栈跟踪记录将指引你去修复。
StackOverflowException 是一种情况,堆栈跟踪可以获取你设置忽略或重启应用程序而丢失的未处理的异常信息。
Note on Debugging Core: For the rare cases where the Photon core raises an unexpected exception we recommend setting “ProduceDump” is always set for details see Photon Core Debugging” - sending us the generated dump files and logs will help us to fix the issue.
注意在调试核心时:罕见的情况下提升Photon核心触发一个未处理的异常,我们建议总是设置为“ProduceDump”,详细信息请参阅Photon核心调试——我们生成的转储文件和日志将帮助我们解决这个问题。
Logging Unhandled Exceptions 记录未处理的异常
As depicted in the figure below an unhandled exception event is raised first in the context of the custom application (1) where the developer can log the exception in any way he requires to c) - please also refer to sample code Lite, Lite Lobby, etc. In a second step the CLR then raises the event in the default application domain (2) - which in the case of Photon is the PhotonHostRuntime. Because of this Photon is able to log the exception in b).
下面的图中描绘了事件引发未处理的异常,首先在自定义应用程序的上下文(1)开发人员可以以任何方式记录异常他需要c)——也请参考样本代码Lite,Lite Lobby,等等。在第二步CLR触发事件在默认应用程序域(2),而在此例中Photon是PhotonHostRuntime的。 由于这种Photon能记录异常在b)。
Photon Loggingfile default path/filenames
Photon日志文件默认路径/文件名
Configuring the UnhandledException Policy 配置未处理异常的策略
<Runtime
Assembly="PhotonHostRuntime, Culture=neutral"
Type="PhotonHostRuntime.PhotonDomainManager"
UnhandledExceptionPolicy="Ignore"
UnhandledExceptionPolicy
can be:
ReloadAppDomain,
Ignore
or
TerminateProcess
未处理异常策略可以是:重新加载程序域、忽略、终止进程
Photon Core Debugging Photon核心调试
<!-- Instance settings -->
<Instance1
...
ProduceDumps = "TRUE"
DumpType = "Full"
MaxDumpsToProduce = "2"
...
ProduceDumps can be: TRUE or FALSE. DumpType: Full, Maxi or Mini
转储文件可以是:True或者False。转储类型可以是:全部、最大、最小