CreateCompatibleDC(IntPtr.Zero) returns IntPtr.Zero

半世苍凉 提交于 2019-12-13 17:34:02

问题


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

Third Party 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();
        }

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);
    }

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

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

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.

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.


回答1:


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

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.

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



来源:https://stackoverflow.com/questions/57437597/createcompatibledcintptr-zero-returns-intptr-zero

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!