托管窗口服务中的令牌泄漏

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() 放在代码末尾来检查终结线程是否开始。

【讨论】:

以上是关于托管窗口服务中的令牌泄漏的主要内容,如果未能解决你的问题,请参考以下文章

最佳窗口服务器[关闭]

403 错误 - 模态窗口中的 CSRF 令牌

Angular Node - 在打开新的浏览器窗口时向服务器发送令牌

Activity 在使用 volley 时泄漏了窗口

Android 'BadTokenException 窗口令牌 android.os.BinderProxy@4250d6d8 无效',前台服务正在运行

从 javascript [spotify auth] 中的弹出窗口获取访问令牌 url