Definitely NO. However, the reason is not in PixelShader itself, but in use in ShaderEffect .
Almost all implementations of custom Shader Effects for WPF are based on Microsoft.NET 3.5 samples that have not been updated for .NET 4.0. It was good to use a singleton PixelShader instance for all effects, which only supported ps_2_0 shaders. With .NET 4.0, Microsoft introduced ps_3_0 pixel shader support (for GPU accelerated devices), and at the same time they introduced a memory leak in the ShaderEffect class.
ShaderEffect monitors its PixelShader property and verifies that it does not use ps_3_0 registers for ps_2_0 bytecode, thanks to a strong subscription to the PixelShader internal event called _shaderBytecodeChanged . Therefore, the singleton PixelShader used by multiple instances of ShaderEffect serves as the dominant root for the GC and saves all objects that were used with any instance of the corresponding ShaderEffect . This is a known memory leak that will not be fixed.
If you want to use PixelShader as a singleton without leaks, you have to use hacks at runtime: every time a PixelShader instance is assigned to the PixelShader property of the ShaderEffect class, the _shaderBytecodeChanged PixelShader field must be cleared manually, for example:
var ei = typeof(PixelShader).GetEvent("_shaderBytecodeChanged", BindingFlags.Instance | BindingFlags.NonPublic); var fi = typeof(PixelShader).GetField(ei.Name, BindingFlags.Instance | BindingFlags.NonPublic); fi.SetValue(pixelShader,null);
Of course, these operations can be optimized by creating helper methods at run time by the DynamicMethod or similar mechanisms. However, this should only be used for shaders, which are certainly ps_2_0 or definitely ps_3_0
Aloraman
source share