Repository: dotnet/runtime
File: src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs (C#)

Code before:
                if (!_disposed)
                {
                    _disposed = true;

                    // First dispose the SSL context to trigger native cleanup
                    _sslContext.Dispose();

                    if (disposing)
                    {
                        // Then dispose the buffers
                        _inputBuffer.Dispose();
                        _outputBuffer.Dispose();
                    }
                }
            }

            base.Dispose(disposing);
        }

        [UnmanagedCallersOnly]
        private static unsafe void WriteToConnection(IntPtr connection, byte* data, int dataLength)
        {
            GCHandle h = GCHandle.FromIntPtr(connection);
            Debug.Assert(h.IsAllocated);

            SafeDeleteSslContext? context = (SafeDeleteSslContext?)h.Target;
            Debug.Assert(context != null);

            try
            {
                lock (context._lock)
                {
                    if (context._disposed)
                    {
                        Debug.Write("WriteToConnection: context is disposed");
                        return;
                    }

                    var inputBuffer = new ReadOnlySpan<byte>(data, dataLength);

                    context._outputBuffer.EnsureAvailableSpace(dataLength);
                    inputBuffer.CopyTo(context._outputBuffer.AvailableSpan);
                    context._outputBuffer.Commit(dataLength);
                }
            }
            catch (Exception ex)
            {
                Debug.Write("Exception Caught. - " + ex);
                throw;
            }
        }

Review comment (suggestion):
You can consider switching to new `GCHandle<T>` to avoid this cast

Code after:
                if (!_disposed)
                {
                    _disposed = true;

                    // First dispose the SSL context to trigger native cleanup
                    _sslContext.Dispose();

                    if (disposing)
                    {
                        // Then dispose the buffers
                        _inputBuffer.Dispose();
                        _outputBuffer.Dispose();
                    }
                }
            }

            base.Dispose(disposing);
        }

        [UnmanagedCallersOnly]
        private static unsafe void WriteToConnection(IntPtr connection, byte* data, int dataLength)
        {
            WeakGCHandle<SafeDeleteSslContext> h = WeakGCHandle<SafeDeleteSslContext>.FromIntPtr(connection);
            if (!h.TryGetTarget(out SafeDeleteSslContext? context))
            {
                Debug.Write("WriteToConnection: failed to get target context");
                return;
            }

            lock (context._lock)
            {
                if (context._disposed)
                {
                    Debug.Write("WriteToConnection: context is disposed");
                    return;
                }

                var inputBuffer = new ReadOnlySpan<byte>(data, dataLength);

                context._outputBuffer.EnsureAvailableSpace(dataLength);
                inputBuffer.CopyTo(context._outputBuffer.AvailableSpan);
                context._outputBuffer.Commit(dataLength);
            }
        }

        [UnmanagedCallersOnly]
        private static unsafe PAL_SSLStreamStatus ReadFromConnection(IntPtr connection, byte* data, int* dataLength)
        {
            WeakGCHandle<SafeDeleteSslContext> h = WeakGCHandle<SafeDeleteSslContext>.FromIntPtr(connection);
            if (!h.TryGetTarget(out SafeDeleteSslContext? context))
            {