由于未处理的异常,该进程被终止 - 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(或更高版本),那么您可以通过不使用 &lt;targets async="true"&gt; 而是使用 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 的信息,这对我来说非常危险。您有什么选项可以让我存档或压缩事件查看器日志吗?非常感谢您的帮助。 这是我的 app.config 中的配置 不确定我是否理解您对 EventLog-target 的问题。 Windows 事件日志的上限通常为 64 KB。因此,如果写入超过 64 KB,则它开始丢弃旧项目。如果您正在写入超过 80 GB,那么我认为您应该重新考虑该信息与 Windows-EventLog 相关。也许将 Logger-minLevel 增加到 Warn ? (这听起来又像是一个不同的问题) 是的,避免硬盘已满是正确的,我已将 minlevel 从 Trace 更改为 Warn。谢谢

以上是关于由于未处理的异常,该进程被终止 - WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

wcf HTTP 终止

Linux 内核进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )

WCF 异常记录

Swift:以 NSException 类型的未捕获异常终止

客户端断开连接后,WCF操作未运行

WCF 服务 SecurityNegotiationException