SYSLIB0004: The constrained execution region (CER) feature is not supported
The Constrained execution regions (CER) feature is supported only in .NET Framework. As such, various CER-related APIs are marked obsolete, starting in .NET 5. Using these APIs generates warning SYSLIB0004
at compile time.
The following CER-related APIs are obsolete:
- RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(RuntimeHelpers+TryCode, RuntimeHelpers+CleanupCode, Object)
- RuntimeHelpers.PrepareConstrainedRegions()
- RuntimeHelpers.PrepareConstrainedRegionsNoOP()
- RuntimeHelpers.PrepareContractedDelegate(Delegate)
- RuntimeHelpers.ProbeForSufficientStack()
- System.Runtime.ConstrainedExecution.Cer
- System.Runtime.ConstrainedExecution.Consistency
- System.Runtime.ConstrainedExecution.PrePrepareMethodAttribute
- System.Runtime.ConstrainedExecution.ReliabilityContractAttribute
However, the following CER-related APIs are not obsolete:
- RuntimeHelpers.PrepareDelegate(Delegate)
- RuntimeHelpers.PrepareMethod
- System.Runtime.ConstrainedExecution.CriticalFinalizerObject
Workarounds
If you've applied a CER attribute to a method, remove the attribute. These attributes have no effect in .NET 5 and later versions.
// REMOVE the attribute below. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public void DoSomething() { } // REMOVE the attribute below. [PrePrepareMethod] public void DoSomething() { }
If you are calling
RuntimeHelpers.ProbeForSufficientStack
orRuntimeHelpers.PrepareContractedDelegate
, remove the call. These calls have no effect in .NET 5 and later versions.public void DoSomething() { // REMOVE the call below. RuntimeHelpers.ProbeForSufficientStack(); // (Remainder of your method logic here.) }
If you are calling
RuntimeHelpers.PrepareConstrainedRegions
, remove the call. This call has no effect in .NET 5 and later versions.public void DoSomething_Old() { // REMOVE the call below. RuntimeHelpers.PrepareConstrainedRegions(); try { // try code } finally { // cleanup code } } public void DoSomething_Corrected() { // There is no call to PrepareConstrainedRegions. It's a normal try / finally block. try { // try code } finally { // cleanup code } }
If you are calling
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup
, replace the call with a standardtry/catch/finally
block.// The sample below produces warning SYSLIB0004. public void DoSomething_Old() { RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(MyTryCode, MyCleanupCode, null); } public void MyTryCode(object state) { /* try code */ } public void MyCleanupCode(object state, bool exceptionThrown) { /* cleanup code */ } // The corrected sample below does not produce warning SYSLIB0004. public void DoSomething_Corrected() { try { // try code } catch (Exception ex) { // exception handling code } finally { // cleanup code } }
Suppress a warning
If you must use the obsolete APIs, you can suppress the warning in code or in your project file.
To suppress only a single violation, add preprocessor directives to your source file to disable and then re-enable the warning.
// Disable the warning.
#pragma warning disable SYSLIB0004
// Code that uses obsolete API.
// ...
// Re-enable the warning.
#pragma warning restore SYSLIB0004
To suppress all the SYSLIB0004
warnings in your project, add a <NoWarn>
property to your project file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);SYSLIB0004</NoWarn>
</PropertyGroup>
</Project>
For more information, see Suppress warnings.