Converting TIFF to PDF working unexpectedly

Hi,

We’re converting many Tif and Tiff documents to PDF.
This seems to work but recently we have started seeing rather weird behavior.
Sometimes when we convert a TIF/TIFF our application shuts down and restarts itself.
We didn’t get any errors in our logs so the error wasnt caught by the Try-Catch clause.

Finally i found this error in the event log on the server:

Description: The process was terminated due to an unhandled exception.
Exception Info: System.ObjectDisposedException: Safe handle has been closed.
Object name: ‘SafeHandle’.
at System.Threading.WaitHandle.WaitOneNoCheck(Int32 millisecondsTimeout)
at #=zRdoZiCfBNcPkOwEr7gA2XOZxDcxrLcw4wApAFDYOZR1wYhUsgQ==.#=z$Jjdj07iUeEm()
at #=zp3xAUc1oAysCLiHu5PrSrER85s3SSrPK0555WjcClVSw5DUPkw==.Clear()
at #=zwZ0deVJwndEhzNrTD$usuSevl3EusRLEEP1YO9s=.#=z0iGusJJzBMrNRx5Fkw==()
at #=zwZ0deVJwndEhzNrTD$usuSevl3EusRLEEP1YO9s=.ReleaseUnmanagedResources()
at Aspose.Imaging.DisposableObject.#=zXi2xAno=(Boolean #=zTJkAnbM=)
at Aspose.Imaging.DisposableObject.Finalize()

I tried to set up a test in the application but couldnt manage to reproduce the error from there.
Finally i managed to reproduce the behavior. We have another webapplication which i can run locally on my computer that calls our API (where the file conversion happens), which i also run locally.
By doing this i’ve managed to debug and found that the exception throws when we save the PDF:

pdf.Save(pdfStream);

Our code looks like this:

        private async Task<string> ConvertTiffToPdf(FileRequestModel file)
        {
            try
            {
                using var pdf = new Aspose.Pdf.Document();
                await using var pdfStream = new MemoryStream();
                await using var ms = new MemoryStream(Convert.FromBase64String(file.FileBase64));
                var myImage = new Bitmap(ms);

                var dimension = new FrameDimension(myImage.FrameDimensionsList[0]);
                var frameCount = myImage.GetFrameCount(dimension);

                for (int frameIdx = 0; frameIdx <= frameCount - 1; frameIdx++)
                {
                
                    var page = pdf.Pages.Add();

                    myImage.SelectActiveFrame(dimension, frameIdx);
                    var currentImage = new MemoryStream();
                    myImage.Save(currentImage, ImageFormat.Tiff);
                    var image = new Image { ImageStream = currentImage};

                    image = DownScaleImageToA4(myImage.Height, myImage.Width, image);
                    SetPageInfo(page);

                    image.IsBlackWhite = true;

                    page.Paragraphs.Add(image);
                }

                OptimizePdf(pdf);

                pdf.Save(pdfStream);
                pdfStream.Position = 0;
                pdf.FreeMemory();
                myImage.Dispose();
                return Convert.ToBase64String(pdfStream.ToArray());
            }
            catch (Exception e)
            {
                _logger.Log(e, "Exception in");
                throw new ConversionException("Konverteringen av " + file.FileName + " gick fel.");
            }
        }

       private Image DownScaleImageToA4(int height, int width, Image img)
        {
            if (height > PageSize.A4.Height || width > PageSize.A4.Width)
            {
                if (height - PageSize.A4.Height > width - PageSize.A4.Width)
                {
                    img.FixHeight = PageSize.A4.Height;
                    img.FixWidth = width * (PageSize.A4.Height / height);
                }
                else
                {
                    img.FixWidth = PageSize.A4.Width;
                    img.FixHeight = height * (PageSize.A4.Width / width);
                }
            }

            return img;
        }

     private void SetPageInfo(Page page)
        {
            page.PageInfo.Height = PageSize.A4.Height;
            page.PageInfo.Width = PageSize.A4.Width;
            page.PageInfo.Margin.Bottom = (0);
            page.PageInfo.Margin.Top = (0);
            page.PageInfo.Margin.Right = (0);
            page.PageInfo.Margin.Left = (0);
        }

     private void OptimizePdf(Aspose.Pdf.Document pdf)
        {
            pdf.OptimizeSize = true;
            pdf.Optimize();
            pdf.OptimizeResources(OptimizationOptions.All());
        }

I tried to upload my testfile but it looks like you don’t support uploading TIF. :slight_smile:

@Timpa_elite,

The website displays the types that you can upload, one of them is zip. Can you zip your file and upload it so I can try to replicate the problem?

My bad :slight_smile:
I made 70 copies on this file and ran them after each other, then the error happened.
For some reason it doesn’t happen from my test but only when i call the api with the files as a list with base64 string from another project.

TIF_testfil_001 - kopia - kopia - kopia - kopia.zip (1.1 MB)

@Timpa_elite,

Since it will be difficult for me to replicate the problem I have some questions and advice.

What version of Aspose PDF are you using?
What version of Net are you using?

We have to understand that the error is happening because you are disposing an object which is still being used by a different thread.

Does the error still happen if you comment the following line: myImage.Dispose();

I searched for people who got the exception “Exception Info: System.ObjectDisposedException: Safe handle has been closed.
Object name: ‘SafeHandle’.”

Most of the time is for bad usage of the using block.

Review your references, and your usings because I have the feeling that may be where the issue is in.

Maybe remove the using and let the garbage collector by itself get them when they have on reference.

If you notice you have a problem(Memory leak), somewhere in your code are keeping reference to the objects so they cannot be properly disposed.

I am sorry I cannot tell you exactly where the issue is but I will remove usingd and manual disposes.
Check if your memory usage is getting higher, which means the systems cannot dispose some objects and start from there.

Hi,

I tried to remove all the usings, no success.
Then i tried to comment out most of the code, converted some files to see if it worked and step by step uncomment a line to narrow down where the exception happens.
Finally we managed to locate it, it’s when we set the property:

image.IsBlackWhite = true;

that we sometimes get an exception.

We’re running .NET 6 and the latest version of Aspose.PDF, 23.1.1.

Is this a common exception and is there any fix on the way, or for now a workaround?

@Timpa_elite,

This is not a common exception.

Is the way you made the code. I am not sure how to avoid it.

You can verify if the image is not null before calling that. But again, is very strange.

You need to research why that exception happened in .net as I said.

It is because an object is manually disposed (Something you code) but was been used in another thread.

Can you show me a way to convert Tiff to PDF that you are sure works?

@Timpa_elite,

The conversion you are using seems to be okay, but I would pay attention to how you dispose the object. If I could point out exactly to which line or where exactly is the issue I would let you know right away.

I cannot replicate the issue in my local code. But I did a simple search over the internet to see when this exception happened. Most of the time is by bad implemented using, manually setting variables to null while the object is still in use or manually calling a dispose method of an object while they are still in use.

If I were you I will search for the exception and look at what other programmers did to avoid this issue.
I believe this has nothing to do with Aspose.Pdf, or we would see this issue all over our forum, but how you code the solution.

One more question you need to analyze is(general questions, not necessarily related to the code)

why I am using manually dispose of objects?
is GC not capable of doing it automatically?
If so, where in my code are the references that are not released properly?

If you answer all of those question you will be closer to know how to change your code ot avoid this exception.

Yes,
That’s why i have tried to remove all manual disposing of objects and even all the usings so nothing should be disposed in beforehand.
The only thing that helps in all cases is if i turn of the IsBlackWhite property, isn’t that strange?

@Timpa_elite,

Can you humor me and move that line just after the image is created?

Does still throw the error??

The “DownScaleImageToA4” line?
I’ve tried that before without any success, i tried it again but same thing.

This is the callstack if that’s of any interest to you.
callstack.png (23.2 KB)

@Timpa_elite,

On final thought, I do not know if it will be of any help but maybe stop using

pdf.OptimizeResources(OptimizationOptions.All());

Since this method is obsolete in .Net Core.

I took the time to build a small MVC web, with an input to upload the files.
Then i call an API to convert the Tiff files to PDF.
This is replicating pretty much exactly how our solution works.
Doing this i could replicate the exception, toggling the “IsBlackWhite” still seems to be the solution for me.

Please do try it and see if you get the same behavior.
Open the “TifToPdf” folder and open that solution, then set multiple startup projects.

[timppaa/AsposeConvertTiffToPdfErrorSample (github.com)](https://github.com/timppaa/AsposeConvertTiffToPdfErrorSample)

Please let me know if you get the same behavior as me with this solution.

@Timpa_elite,

Thanks for asking. I think you should have the code you need to make the Aspose parts of your solution work - in terms of more general parts of your code unconnected to Aspose I’m not able to help with those.
But if you feel you still need more help with Aspose-related code then please let me know and I’ll continue to help.

How is this not Aspose-related code?
The exception is being thrown when i set the “IsBlackWhite” flag, have you tried the solution i uploaded?

@Timpa_elite,

Yes, I downloaded your repo and run it locally uploading the picture you uploaded before.

How many times do I have to run the code in order for the exception to happend?

Copy the file, let’s say 50 copies then upload them all and start converting. That should trigger the exception everytime. It differs when the exception happens, sometimes on the fifth file and sometimes on the twentieth etc, even though it’s the same file.
Also make sure the “image.IsBlackWhite” is set to true.

@Timpa_elite,

So after some testing I was able to replicate the error with 20 or 30 images, but noticed that issue was tied to Aspose.Drawing version 22.10. So I downloaded the latest one, Aspose.Drawing 23.2.

I was able to succefully made those files, which prior to this update I was not.

After this change I got an error produced in this library:

C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.14\System.Private.CoreLib.dll.

With this information I will contact the development team.

Can you do me a favor and update Aspose.Drawing, and tell me if you see the same error?