由于未处理的异常,该进程被终止 - WCF 服务
Posted
技术标签:
【中文标题】由于未处理的异常,该进程被终止 - WCF 服务【英文标题】:The process was terminated due to an unhandled exception - WCF service 【发布时间】:2018-10-27 12:54:56 【问题描述】:所以我创建了一个 WCF 服务,它从客户那里获取消息并将它们解析为所需的输出,然后通过 TCP/HTTP/FTP 等将它们发送给其他客户。 此 Windows 服务为使用 TPL 创建的每个客户提供了长时间运行的线程。
所以对于日志记录,我使用了 NLOG,使用以下配置记录到文件和事件查看器
<target xsi:type="File" name="flatfile" layout="$longdate $uppercase:$level $message $exception:format=tostring,StackTrace"
archiveAboveSize="2000000" archiveFileName="$basedir/logs/archive/$shortdate-#####.engine.log" archiveNumbering="Sequence" archiveEvery="None"
maxArchiveFiles="100" fileName="$basedir/logs/engine.current.log" keepFileOpen="true" concurrentWrites="true" />
<target xsi:type="EventLog" name="eventlog" layout="$longdate $uppercase:$level $message $exception:format=tostring $StackTrace" log="Application" source="Nuance Interface Engine Service" eventId="$event-properties:EventID" />
即使我添加了 concurrentWrites="true",当我在 20 多个小时后启动 WCF 服务时,我在事件查看器中仍出现以下错误
Application: MyWcfService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.OutOfMemoryException
at System.Text.StringBuilder..ctor(System.String, Int32, Int32, Int32)
at NLog.Layouts.SimpleLayout.GetFormattedMessage(NLog.LogEventInfo)
at NLog.Targets.FileTarget.GetFormattedMessage(NLog.LogEventInfo)
at NLog.Targets.FileTarget.GetBytesToWrite(NLog.LogEventInfo)
at NLog.Targets.FileTarget.Write(NLog.Common.AsyncLogEventInfo[])
at NLog.Targets.Target.WriteAsyncLogEvents(NLog.Common.AsyncLogEventInfo[])
at NLog.Targets.Wrappers.AsyncTargetWrapper.ProcessPendingEvents(System.Object)
at System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireQueuedTimerCompletion(System.Object)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
请有人指导我这个问题发生在哪里,我认为多个线程正在访问这个日志文件,因此我在 nlog 的文件目标中添加了 concurrentWrites="true" 属性。
在 1 秒后出现上述错误,我在事件查看器中看到另一个错误。
Faulting application name: Hl7ic.Engine.View.exe, version: 18.0.1.160, time stamp: 0x5af5cd1f
Faulting module name: KERNELBASE.dll, version: 6.3.9600.18938, time stamp: 0x5a7dd8a7
Exception code: 0xe0434352
Fault offset: 0x00015ef8
Faulting process id: 0x1074
Faulting application start time: 0x01d3ea7338d9851c
Faulting application path: C:\Program Files (x86)\MyServices\MyWcfService.exe
Faulting module path: C:\windows\SYSTEM32\KERNELBASE.dll
Report Id: 59b36929-5688-11e8-80ca-005056a80aaa
Faulting package full name:
Faulting package-relative application ID:
【问题讨论】:
您的答案在异常详情中:“异常信息:System.OutOfMemoryException” 是的,我检查过了,但是如何解决这个问题,因为自从项目建立 3 年前以来,我没有更改 NLOG 的配置。我只是在多个线程中运行这些。 您需要分析您的代码库以找出问题所在。如果没有对代码库的广泛了解,就不可能回答这个问题。有些工具允许在某些事件期间进行内存转储,例如调试诊断工具等,因此您可以调查这些内存转储以发现潜在的内存泄漏等。难道是服务是32位进程而不是64位? 是的,你是对的,服务是 32 位的 如果它经常崩溃,而您现在正忙于解决生产问题,我可能会将它重新编译为 AnyCPU,以便它可以作为 64 位进程运行。这至少应该为你争取一些时间,直到你弄清楚你的内存泄漏在哪里。 【参考方案1】:OutOfMemoryException
表示本机内存不足。也许它已被另一个应用程序用完。也许它已被您的应用程序用完。也许您的 32 位应用程序已用完其 2 GB 的内存地址空间。
要诊断此错误,然后使用 Process Explorer 捕获使用过多内存的应用程序的 Fulldump。然后尝试使用 Visual Studio 或 WinDbg 调查内存转储文件。
要从雷达中删除 NLog,您可以升级到 NLog 4.4.6(或更高版本)。它将减少与 70 pct 的内存分配。从旧版本(使用 FileTarget 时)
如果运行 NLog 4.4.6(或更高版本),那么您可以通过不使用 <targets async="true">
而是使用 default-wrapper
来进一步优化 NLog:
<targets>
<default-wrapper xsi:type="AsyncWrapper" timeToSleepBetweenBatches="0" />
<target .... />
<target .... />
</targets>
另见https://github.com/NLog/NLog/wiki/Performance
【讨论】:
您好 Rolf,很抱歉升级 NLog 版本到 4.5.4 后的延迟响应没有发生内存异常,我已经运行了 30 小时的服务,感谢您的帮助。现在出现了新问题,nlog 的事件查看器配置在 24 小时内转储了近 80GB 的信息,这对我来说非常危险。您有什么选项可以让我存档或压缩事件查看器日志吗?非常感谢您的帮助。Warn
? (这听起来又像是一个不同的问题)
是的,避免硬盘已满是正确的,我已将 minlevel 从 Trace 更改为 Warn。谢谢以上是关于由于未处理的异常,该进程被终止 - WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )