Search code examples
c#c++multithreadingmemory-leakscom

How to prevent objects used by threads from being disposed? How to control the lifetime of the object?


Consider we have C# and C++ talking via COM. Inside C++ we have two classes named ProcessText and Text.

Text Class: Holds the Text details object like string, numberOfPages, etc

ProcessText Class: It reads the files in the given input directory and process the files using C# component with the help of 2 functions

ReadAll() Method: It reads all the file in the directory creates Text object and passes it down to ProcessAll().

ProcessAll() Method: Consider MultiThreading Scenario where the input Text object to C# component is fed to the threads.

Inside ProcessAll() the scope of the Text object is finished I need some mechanism to prevent the object from going out of scope until the thread finishes the processing and if this is not possible at least trigger C# component to stop processing on that Text Object.

What I specifically wants can it be achieved by using Destructor of C++ class? If during destruction of Text Object we query C# component about the status of the Text object and can we block its memory from destruction without waiting on the thread to complete operation? Also if the object is not destroyed but still the memory will be freed. Can we prevent the memory from getting freed? If memory still holds value as memory leak can it be used by threads safely and also can it be taken up the OS to write some other things? If it can be taken up by the OS can we block this memory by using pointer and size of the object?


Solution

  • In general, all you have to do in C# is GC.KeepAlive(text) at the end of the thread.

    If that is not enough (e.g. because you need to keep those Text objects alive until after all threads have finished their job), then you must keep a reference to the Text objects. Perhaps the easiest way to achieve this is to use PLINQ, e.g. files.AsParallel().Select(...).ToList() (or SelectMany(...)).

    This way, by the end of the parallel enumeration, you'll have references to all Text objects, assuming that's what you'll return from Select (or SelectMany). You then need to control for how long you need to reference the new enumerable, e.g. you may have to use GC.KeepAlive(texts) at the end of the ProcessAll() method.