Prevent garbage collection for managed reference which is used in unmanaged code

三世轮回 提交于 2020-01-03 07:24:12

问题


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.


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/14735520/prevent-garbage-collection-for-managed-reference-which-is-used-in-unmanaged-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!