Timeout for Aspose.Words.Document.Save method

Hi,

I would like to know if there’s anyway we could add a timeout to this method,

Aspose.Words.Document doc = new Aspose.Words.Document(inputFileName);
doc.Save(Path.ChangeExtension(inputFileName, ".pdf"));

As at the moment, for number of documents - it keeps running for several hours…, I looked at the API’s documentation but couldn’t find anything specific to time out.

Hi there,

Thanks for your inquiry. Unfortunately, there is no way to know how much time you should wait
before the conversion ends. We will consider adding a Callback event
that notifies you the progress of conversion. I linked your request to
the appropriate issue (WORDSNET-7187) in our issue tracking
system and you will be notified as soon as this feature is
supported. We apologize for your inconvenience.

Aspose.Words does support multi-threading. The only thing you need to make sure is that you
always use separate Document instances per each thread. One thread should use one Document object.

You may stop the execution of your program after some specific time. Please read following web links for your kind reference. Hope this helps you.
http://stackoverflow.com/questions/3607359/stop-executing-code-in-thread-after-30s
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/7a2f3ay4(v=vs.90)

Hi Tahir,

Thanks for the suggestions, but unfortunately aborting the Thread doesn’t release all the memory it occupied. I am trying to timeout the thread after 5 minutes but memory that it takes remains occupied…

RunWithTimeout(() =>
{
    Aspose.Words.Document doc = new Aspose.Words.Document(inputFileName);
    doc.Save(Path.ChangeExtension(inputFileName, ".pdf"));
}, TimeSpan.FromMilliseconds(1000 * 60 * 5));

public static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout)
{
    Thread workerThread = new Thread(threadStart);
    workerThread.Start();
    bool finished = workerThread.Join(timeout);
    if (!finished)
    {
        workerThread.Abort();
    }
    return finished;
}

I would appreciate a quick solution as the problem is bring down our production environment and causing great loss. I would try to provide you with a dummy document but it might take some time as company documents are strictly confidential.

Regards

Muhammad Raja

Hi there,

Thanks for your inquiry. Could you please attach your input Word document here for testing? I will investigate the issue on my side and provide you more information.

Tahir,

I would love to add this document but because of company’s policies I am unable to do so, but I am pretty sure you can replicate the issue easily by adding a dummy document ?

I am just looking into AppDomains to load your assembly and run code through it but it then says,

Type ‘Aspose.Words.Document’ in assembly
‘Aspose.Words, Version=14.10.0.0, Culture=neutral,
PublicKeyToken=716fcc553a201e56’ is not marked as serializable.

This is the code I am using,

AppDomain domain = AppDomain.CreateDomain("New domain name");
string pathToDll = @"C:\Aspose.Words.dll";
Type t = typeof(Aspose.Words.Document);
Object[] constructorArgs = new Object[1];
constructorArgs[0] = inputFileName;
Aspose.Words.Document myObject = (Aspose.Words.Document)domain.CreateInstanceFromAndUnwrap(
pathToDll,
t.FullName,
false, //ignoreCase
0, //bindingAttr
null, //binder, use Default 
constructorArgs, //the constructor parameters
null, //culture, use culture of current thread
null);
myObject.Save(Path.ChangeExtension(inputFileName, ".pdf"));

I am looking for any solution which would abort the Thread with memory release… as the issue is on our production servers.

Regards

Muhammad Raja

Hi there,

Thanks for your inquiry. I have tested the scenario and have not found the shared issue while using latest version of Aspose.Words for .NET 14.11.0. I would suggest you please upgrade to the latest version (v14.11.0) from here and let us know how it goes on your side.

I suggest you please call GC.Collect method after aborting the thread. Hope this helps you. If the problem still remains, please share following detail for further investigations.

  • Please attach the dummy document
  • Please share the steps which you are using to check the memory issue.

It took me a while but I managed to get you a test document(attached), which takes memory usage to 100% and stays there even after aborting the Thread. GC.Collect() didn’t helped to bring memory usage down neither is the recommended way of solving this issue.

Just to clear, the reason for me to contact you is not to find the issue with the provided document but to find out how could we stop document conversions memory leaks following best practices.

What we are really expecting from your API is to provide a safe way out in case someone uploads a document with problems and not just break everything running on the server.

Could you also confirm if your latest update actually solves the memory leak issue or it’s just an assumption that it will fix the issue…

Regards

Muhammad Raja

Hi,

Just to confirm, I tried your suggested version 14.11.0 the latest from nuget gallery, but problem remains as it is…

The steps I followed are as following,

  • I created a new console app.
  • Added latest packge of Aspose.Words from Nuget gallery.
  • Created a folder in C drive with name “test” and added a dummy txt file to it, and using code below (modified file name obviously) it converted the file successfully.
  • Deleted all files in the folder and added the file I just sent you to it, then used this code again to convert it,
string inputFilename = @"C:\test\Test9.doc";
Aspose.Words.Document doc = new Aspose.Words.Document(inputFilename);
doc.Save(Path.ChangeExtension(inputFileName, ".pdf"));

Memory usage was only 30% before and now it’s 100% for more then 20 minutes…

Regards

Muhammad Raja

Hi Muhammad Raja,

Thanks for sharing the detail. I have tested the scenario and have found the out of memory exception while converting Doc to Pdf. For the sake of correction, I have logged this problem in our issue tracking system as WORDSNET-11242. I have linked this forum thread to the same issue and you will be notified via this forum thread once this issue is resolved. We apologize for your inconvenience.

Regarding memory leakage issue, I have tested the scenario using following code example at Windows 7 (64 bit), 8 GB Ram and .NET Framework 4.0 and have not found the shared issue.

Console.WriteLine("Memory used
before using Aspose.Words:
{0:N0}",
GC.GetTotalMemory(false));
RunWithTimeout(() =>
{
Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Test9.doc");
doc.Save(MyDir + "Out.pdf");
}, TimeSpan.FromMilliseconds(1000 * 60 * 1)); // * 60 * 5
Console.WriteLine("Memory used before collection: {0:N0}",
GC.GetTotalMemory(false));
// Collect all generations of memory.
GC.Collect();
Console.WriteLine("Memory used after calling GC.Collect: {0:N0}",
GC.GetTotalMemory(true));
Console.ReadLine();

Hi Tahir,

I am glad you are able to replicate half of the issue on your side, I am using Microsoft Server 2012 with .Net 4.0 and Memory is 8GB.

I attached screenshot of memory leak too… GC.Collect(); is not doing the job, neither it is recommended code to add… I hope your development team fix the issue soon instead.

Thanks

Muhammad Raja

Hi Muhammad Raja,

Thanks for sharing the detail. Could you please restart the same console application and check if the memory is still same as 1, 030, 708, 112 ?

If I will close the process “ConsoleApplication1…” obviously it will dispose all the objects in the memory which were consumed by this process…

The issue is on our production server and because it’s understood that GC.Collect doesn’t always guarantees success, our Team lead won’t allow me to add it to the code., I temporarily terminating the thread on the production for now so that it would not eat up all of the memory and it automatically clear the memory itself after hour or 2.

http://stackoverflow.com/questions/233596/best-practice-for-forcing-garbage-collection-in-c-sharp?lq=1

http://stackoverflow.com/questions/118633/whats-so-wrong-about-using-gc-collect

I added 2nd screenshot just in case.

Hi Muhammad Raja,

Thanks
for sharing the detail. I have tested the scenario and have managed to reproduce the same issue at my side. I have logged this issue as WORDSNET-11250 in our issue tracking system and you will be notified via this forum thread once this issue is resolved.

Moreover, I have logged a feature request as WORDSNET-11251 to terminate the Document.Save method after specific time.

We apologize for your inconvenience.

Thanks.

Would it be possible for you to tell me usually how long does it takes for your development team to fix such issues?

Regards

Muhammad Raja

Hi Muhammad Raja,

Thanks for your inquiry. I would
like to share with you that
issues are addressed and resolved based on first come first serve
basis. Currently, your issues are pending for analysis and are in the
queue. We will update you via this forum thread once these issue are resolved.

Thank you for your patience and understanding.

The issues you have found earlier (filed as WORDSNET-11242) have been fixed in this .NET update and this Java update.


This message was posted using Notification2Forum from Downloads module by aspose.notifier.

Are these issues resolved ? I have been waiting for more then 3 months now…

Hi Muhammad Raja,

Thanks for your inquiry via live chat. We do understand your situation,
however I am afraid, at the moment we can’t provide you the ETA for
these issues/features. Since you reported these issues via Aspose normal
forum and these issues were logged with ‘Normal Priority’ in our issue
tracking system.

MuhammadRaja:

ask dev team what has been holding them back and what would be ETA for normal, PS and ES subscription for this issue

Please note that
ES/PS support does not guarantee any immediate resolution of issues (because
it might be dependent on other issues or feature which needs to be implemented)
but under this model, the development team starts investigating the
problem on high priority. For further details, please visit Support Options.

I have requested the development team to share the ETA for following issues if you buy ES/PS subscription. As soon as any information is shared by them, I will be more than happy to share that with you.

WORDSNET-11251 : Add option in PdfSaveOptions to terminate the Document.Save method after specific time
WORDSNET-11365 : An extra line on page 2 in AW pdf output
WORDSNET-11250 : Aborting the Thread doesn’t release all the memory

Thanks for your patience and understanding.

Hi Muhammad Raja,

Thanks for your patience. Regarding WORDSNET-11251 and WORDSNET-11250, Thread.Abort method is unsafe way for interrupt Aspose.Words execution. For example, file descriptor may not be closed. Aspose.Words has special interruption way using class InterruptionToken. Please use following code examples to achieve your requirements. We will close WORDSNET-11251 and WORDSNET-11250 as ‘Not a bug’.

Please let us know if you have any more queries.

/// 
/// My Aspose document.
/// 
public class MyDocument : Aspose.Words.Document
{
    public MyDocument(string fileName) : base(fileName) { }
            
    public bool TryToSave(string fileName, int timeout)
    {
        InterruptionToken token = new InterruptionToken();
        bool finished = SaveWithTimeout(token,
        () =>
        {
            token.BindToCurrentThread();
            try
            {
                Save(fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Interrupted");
            }
        }, timeout);
        return finished;
    }
    private bool SaveWithTimeout(InterruptionToken token, ThreadStart threadStart, int timeout)
    {
        Thread workerThread = new Thread(threadStart);
        workerThread.Start();
        bool finished = workerThread.Join(timeout);
        if (!finished)
        {
            token.Interrupt();
        }
        return finished;
    }
}

MyDocument myDoc = new MyDocument(MyDir + "in.docx");
bool done = myDoc.TryToSave(MyDir + "Out.pdf", 1000);
Console.WriteLine(done? "Converted" : "Interrupted by timeout.");

Hi Muhammad Raja,

Thanks for your patience. It is to inform
you that the issue which you are facing is actually not a bug in
Aspose.Words. So, we have closed this issue (WORDSNET-11250) as ‘Not a
Bug’. I am quoting product team comments here for your reference.

*Aspose.Words has some internal static objects which remain live after GC.Collect(…) because these static fields are GC roots. If you replace a call to Aspose.Words with a call to a dummy class below, you will see the same “memory leak”.

The TestMe class has a static array of ints that does not get GCed until you force GC. If your concern is about this case in multi-threading scenarios, it should be no problem, since statics are only created once and are reused for each subsequent thread.*

Console.WriteLine("Memory used before using dummy class : {0:N0}", GC.GetTotalMemory(false));
RunWithTimeout(() =>
{ var test = new TestMe(100); }, TimeSpan.FromMilliseconds(1000 * 60 * 1)); // * 60 * 5
Console.WriteLine("Memory used after thread termination : {0:N0}",
GC.GetTotalMemory(false));
public class TestMe
{
    private readonly int[] dummyEls;
    public TestMe(int nEls)
    { dummyEls = new int[nEls]; }
    private static readonly int[] gStaticData = new int[10000];
}