In my web application, I'm utilizing a PDF library which is using a native DLL.
I'm using it for two very different purposes in two completely separate (and isolated by NuGet) parts of the web application.
Upon application start, I load the library DLL and thus lock the file. Then, rebuild requires completely terminating the application which takes much time and disrupts our workflow.
We cannot load and unload the DLL on every operation, as the operation will be executed lots of times in bursts. This will also not be thread safe.
So in order to alleviate this, I have decided to make a small wrapper to the PDF library that:
- for every operation (it will only have 2) it will check if the library is loaded.
- If not, it loads it. After the operation, it sets a timer that will unload the DLL in, let's say 10 seconds.
- If another operation is executed within this timeframe, the timer is reset.
This is the code I have written so far to achieve this, appreciate any pointers.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace PdfLibrary
{
public static class PdfLibrary
{
static object Lock = new object();
static TimeSpan Timeout = new TimeSpan(0, 0, 10);
static bool IsLoaded = false;
static Timer UnloadTimer = new Timer();
static PdfLibrary()
{
UnloadTimer.Interval = Timeout.TotalMilliseconds;
UnloadTimer.Elapsed += (_, __) => Unload();
}
private static void Unload()
{
UnloadTimer.Stop();
lock (Lock)
{
// ... unloads pdf library ...
}
}
static void DoWhenLoaded(Action action)
{
if (!IsLoaded)
{
lock (Lock)
{
if (!IsLoaded)
{
// ... loads pdf library ...
}
}
}
action();
UnloadTimer.Stop();
UnloadTimer.Start();
}
public static IEnumerable<string> ExtractText(Stream inputStream)
{
IEnumerable<string> result = null;
DoWhenLoaded(() => {
// ... sets result ...
});
return result;
}
}
}