-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
EDITED by @stephentoub on 1/20/2023:
The issue at this point tracks an analyzer that would flag use of GC.KeepAlive(local) usage in the context of C# iterators, async methods, and anywhere else the C# compiler does a significant method rewrite such that a "local" isn't actually local, e.g. where that local is lifted to a state machine and the use of GC.KeepAlive has little to no impact, e.g.
object o = new object();
yield return o;
GC.KeepAlive(o);Description
According to Eric Lippert there is no need to pin a local delegate or keep a GCHandle when passing a delegate via PInvoke as long as you use GC.KeepAlive to keep the delegate alive for as long as the native code could call it. https://stackoverflow.com/a/5465380/78561
However while this seems to be true for the dotnet runtime in mono this does not work and we are getting crashes when the callback happens.
We have found that in mono we need to keep a Normal GCHandle to the delegate GC.KeepAlive does not seem to be enough.
This behaviour needs to be consistent across the mono/dotnet runtimes.
This issue was found when using Xamarin.Android
Reproduction Steps
var taskCompletionSource = new TaskCompletionSource();
MyDelegateType myDelegate = () => taskCompletionSource.SetResult(true);
NativeMethods.MyNativeMethod(myDelegate);
await taskCompletionSource.Task;
GC.KeepAlive(myDelegate);
Expected behavior
GC.KeepAlive should prevent the delegate from being collected until the delegate callback has happened.
Actual behavior
Crash, usually with NullReferenceException
Regression?
No response
Known Workarounds
Get a normal GCHandle to the delegate instead of using GC.KeepAlive
var taskCompletionSource = new TaskCompletionSource();
MyDelegateType myDelegate = () => taskCompletionSource.SetResult(true);
var gcHandle = GCHandle.Alloc(myDelegate, GCHandleType.Normal);
NativeMethods.MyNativeMethod(myDelegate);
await taskCompletionSource.Task;
gcHandle.Free();
Configuration
No response
Other information
No response