Reputation: 13043
My C# application uses wrapped C++ code for calculations.
C++ header:
__declspec(dllexport) void SetVolume(BYTE* data, unsigned int width);
C++/CLI wrapper:
void SetVolume(array<Byte>^ data, UInt32 width)
{
cli::pin_ptr<BYTE> pdata = &data[0];
pal->SetVolume(pdata, width);
}
C# :
public startCalc()
{
byte[] voxelArr = File.ReadAllBytes("Filtered.rec");
palw.SetVolume(voxelArr, 490);
//GC.KeepAlive(voxelArr); makes no sense
}
The C++ SetVolume
function starts asynchronous calculations. voxelArr
is not referenced from the managed side any longer and is garbage collected.
How can I prevent the garbage collection for this reference until the unmanaged code finished it's work without to declare voxelArr
as global variable? Creating a copy of array isn't an option as there is really a lot of data. Active wait inside of startCalc()
isn't good too.
Upvotes: 10
Views: 4387
Reputation: 13819
Another Alternative to your current approach:
Consider making the array global again, create and pin it once at the start, then reuse it whenever you need it. Objects as large as these should not be created on a whim, pool them. Only unpin and release it when you need to recreate it with a larger size
Storing the object in a global pool will prevent it from being garbage collected. You do not strictly speaking have to worry about pinning an object this large, but do so for consistency
Upvotes: 1
Reputation: 564691
You can use GCHandle.Alloc
(voxelArr,
GCHandleType.Pinned
)
to pin the array manually so the GC won't move or clean it.
You would then have to Free the handle when you knew the method was complete, which would require some form of callback for the completion.
Upvotes: 13