CreateCompatibleDC(IntPtr.Zero)返回IntPtr.Zero [英] CreateCompatibleDC(IntPtr.Zero) returns IntPtr.Zero

查看:56
本文介绍了CreateCompatibleDC(IntPtr.Zero)返回IntPtr.Zero的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为一个班级提供以下代码.这是一个类的初始化.

I have the following code for a class. This is the initialize of a class.

第三方DLL

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        protected void initialize()
        {
            if (_initialized)
            {
                return;
            }
            if (_hdc == IntPtr.Zero)
            {
                _hdc = GDI32.CreateCompatibleDC(IntPtr.Zero);
                if (_hdc == IntPtr.Zero)
                {
                    throw new GDIException("Failed to create compatible device context.");
                }
            }
            if (_hFontOld == IntPtr.Zero)
            {
                _hFont = FontSettings.GenerateHFont(_fontSetting, _hdc, _dpi, _forceFixedPitch);
                _hFontOld = GDI32.SelectObject(_hdc, _hFont);
            }
            _initialized = true;
            updateHeightAndWidth();
        }

对不起,我没有发布该Dispose.这里是!.这是一个第三方DLL,每生产3到4个小时就会导致此错误.我们公司使用此第三方软件.升级之前未发生此错误. 第三方DLL.

Sorry I didn't post the Dispose. Here it is!. This is a 3rd party DLL causing this error every 3- 4 hrs on production. Our company uses this 3rd party software. This error didn't happen before the upgrade. Third Party DLL.

protected virtual void Dispose(bool isDisposing)
    {
        if (_isDisposed)
        {
            return;
        }
        releaseOldBitmap();
        if (_hFont != IntPtr.Zero)
        {
            if (_hFontOld != IntPtr.Zero && _hdc != IntPtr.Zero)
            {
                GDI32.SelectObject(_hdc, _hFontOld);
            }
            if (GDI32.DeleteObject(_hFont))
            {
                _hFont = IntPtr.Zero;
            }
        }
        if (_hdc != IntPtr.Zero && GDI32.DeleteDC(_hdc))
        {
            _hdc = IntPtr.Zero;
        }
        _isDisposed = true;
    }

    ~TextPageRenderer()
    {
        Dispose(isDisposing: false);
    }

    public void Dispose()
    {
        Dispose(isDisposing: true);
        GC.SuppressFinalize(this);
    }

此代码在生产中效果很好.但是,在服务器上进行一些负载之后,每隔4小时左右,GDI32.CreateCompatibleDC(IntPtr.Zero)返回IntPtr.Zero,并且异常引发新的GDIException(无法创建兼容的设备上下文.")引发

This code in production works very well. But every 4hrs or so after some load on the server, GDI32.CreateCompatibleDC(IntPtr.Zero) returns IntPtr.Zero and the exception throw new GDIException("Failed to create compatible device context.") is thrown

我们的代码:这就是我在我们的代码中使用第三方DLL的方式

Our code: This is how I use the 3rd party DLL in our code

#region ExternalText

public static DocumentsList ExternalText(Application obApp, int? _RequestCount, int[] _ItemTypeIDs, KeywordIdPairs _Keywords, Constraints _Constraints)
{ 
    var Results = new DocumentsList();
    TextSearchResults textSearchResults;
    var _SearchString = "";
    DateTime startDate;
    DateTime endDate;
    long startDocumentId;
    long endDocumentId;
    var textSearchOptions = new TextSearchOptions();
    var docQuery = obApp.Core.CreateDocumentQuery();

    var textProvider = obApp.Core.Retrieval.Text;
    try
    {
         var keywords = obApp.Core.KeywordTypes;
         startDocumentId = 1;
         endDocumentId = 10;
         docQuery.AddDocumentRange(startDocumentId, endDocumentId); 
        var documentList = docQuery.Execute(Convert.ToInt32(_RequestCount));

        _SearchString = "0916";

        if (!String.IsNullOrEmpty(_SearchString))
        {
            foreach (var document in documentList)
            {
                var keyValueList = new KeyValueList<string, string>();


                if (document != null && document.DefaultRenditionOfLatestRevision != null && document.DefaultRenditionOfLatestRevision.FileType != null && document.DefaultRenditionOfLatestRevision.FileType.Extension == "ctx")
                {

                    textSearchResults = textProvider.TextSearch(document.DefaultRenditionOfLatestRevision, _SearchString, textSearchOptions);
                    foreach (var textSearchResult in textSearchResults)
                    {
                        var t = typeof(TextSearchItem);
                        PropertyInfo[] properties = t.GetProperties();
                        keyValueList.Add(ExternalTextRequest.DocID, document.ID.ToString());
                        keyValueList.Add(ExternalTextRequest.DocName, document.Name);
                        keyValueList.Add(ExternalTextRequest.DocumentType, document.DocumentType.Name);
                        foreach (PropertyInfo pi in t.GetProperties())
                        {
                            if (pi.Name == "SizeX")
                            {
                                keyValueList.Add(ExternalTextRequest.Width, pi.GetValue(textSearchResult, null).ToString());
                            }
                            else if (pi.Name == "SizeY")
                            {
                                keyValueList.Add(ExternalTextRequest.Height, pi.GetValue(textSearchResult, null).ToString());
                            }
                        }
                        Results.Add(keyValueList);
                    }
                }
                else
                {

                }
            }
        }

        return Results;
    }
    catch (UnityAPIException e)
    {
        throw e;
    }
    catch (Exception ex)
    {

        throw ex;
    }
    return Results;

}
enter code here

详细内容是我使用TextDataProvider的代码 我创建TextDatProvider的实例,然后从API调用textsearch.同一代码在2小时内被调用1000次以上.它被称为不同的搜索字符串,即文档ID. TextSearch被大量使用.

The aboce snippet is my code using TextDataProvider I create an instance of TextDatProvider and call the textsearch from the API. The same code gets called more than 1000 times in 2 hrs. It is called for different search string, document ID's. TextSearch is heavily used.

如何解决此问题.这可能是内存泄漏吗? 我无法在测试或开发中实现它. 这是一个引用第三方组件的.NET应用程序.此代码是其组件的一部分.除了已升级的第3方组件外,什么都没有改变.

How do I troubleshoot this problem. Could this be a memory leak? I cannot make it happen on test or development. This is a .NET application that references a 3rd party component. This code is part of their component. Nothing changed except this 3rd party component which got upgraded.

推荐答案

另外,还有一个问题..应用程序池重置会清除GDI对象吗?

Also, one more question..would a App pool reset clear up GDI objects?

您提到您的应用程序正在IIS中运行.当IIS AppPool回收或超时(通常在20分钟后)时,IIS会卸载IIS应用程序的AppDomain. AppDomain有机会处理此事件以进行清理.

You mentioned that your app is running in IIS. When an IIS AppPool is recycled or times out (usually after 20 minutes), IIS unloads the AppDomain for the IIS app. The AppDomain is given a chance to handle this event for clean-up purposes.

对于ASP.NET应用程序,这将是Application_End方法.请确保在此处释放所有GDI对象(包括DC和字体).

For ASP.NET apps this will be the Application_End method. Be sure to release any GDI objects (including DCs and fonts) here.

这篇关于CreateCompatibleDC(IntPtr.Zero)返回IntPtr.Zero的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆