托管窗口服务中的令牌泄漏
Posted
技术标签:
【中文标题】托管窗口服务中的令牌泄漏【英文标题】:Token leak in managed Window service 【发布时间】:2015-03-18 06:31:02 【问题描述】:我在窗口服务中托管了 WCF 服务。我观察到该服务的一些句柄泄漏。经过调查,我发现泄漏的原因是对 *.accdb(MS acsess) 文件执行的数据库操作.为了排除其他可能性(使用 WCF 等),我在 c# 中创建了一个测试窗口服务,并在其 Onstart 方法中启动了一个线程,在该线程中我调用数据库的打开和关闭,我仍然看到令牌泄漏。该服务正在运行是本地系统帐户,并且本地计算机中存在数据库字段。打开和关闭成功。每次我在数据库上调用 Open 时都会生成三个或四个给定类型的令牌,并且在关闭时计数不会减少。因此它们会不断增加。当我以登录用户身份运行服务时,我看不到内存泄漏
protected override void OnStart(string[] args)
ThreadStart t = new ThreadStart(DBConenctionThread);
Thread t2 = new Thread(t);
t2.Start();
void DBConenctionThread()
bool b = true;
String s = @"Driver=Microsoft Access Driver (*.mdb, *.accdb);Dbq=D:\testdatabase\tempelate2.accdb;Uid=;Pwd=;";
while (b)
try
using (OdbcConnection dbConnection = new OdbcConnection(s))
dbConnection.Open();
dbConnection.Close();
catch (NotSupportedException ex)
catch (Exception ex)
这些是从进程浏览器中泄露的令牌的详细信息
名称:NT AUTHORITY\SYSTEM:3e7 类型:令牌 说明:标识安全上下文。
【问题讨论】:
这并不重要,但您调用dbConnection.Close()
是不必要的。 using
块确保将调用 Close
(通过调用 Dispose()
。
您是否尝试过设置IsBackground
标志?但也许我不明白这个问题 - 当你运行无限循环时,这只是一个 Token 吗?
@Dai -Yeah ,我的生产代码中没有 dbConnection.Close() 。我在这里有它,因为我一直在尝试一切。并且想确保它不是 Close 中的错误或其他东西.
@Carsten - 这只是一个示例代码,我必须在我的代码中重现问题。每次我在数据库上调用 Open 并且计数不会减少时,都会生成给定类型的三个或四个令牌关闭。所以他们继续增加。
【参考方案1】:
我有非常相似的问题。所有这些令牌都在 GC 的终结器队列中,准备在终结线程启动时终结。但是因为我们的服务入口点被标记为 [STAThread],所以终结线程从未启动。当我们将属性更改为 MTAThread 时,那些令牌件被 GC 成功回收。你我的 dot'n 有同样的问题,但你可以通过将 GC.WaitForPendingFinalizers() 放在代码末尾来检查终结线程是否开始。
【讨论】:
以上是关于托管窗口服务中的令牌泄漏的主要内容,如果未能解决你的问题,请参考以下文章
Angular Node - 在打开新的浏览器窗口时向服务器发送令牌
Android 'BadTokenException 窗口令牌 android.os.BinderProxy@4250d6d8 无效',前台服务正在运行