Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Project Kotlin suspend APIs as Task<T> instead of raw IContinuation

Abierto
#1,456 2 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
45/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
android, csharp, kotlin
Área
mobile

Línea de trabajo

Reproduce el problema con Xamarin.AndroidX.Health.Connect.ConnectClient 1.1.0.2 usando GetGrantedPermissions y ReadRecords; después, inspecciona cómo se generan estas Kotlin suspend APIs en el binding. Comprueba la compatibilidad existente del generator o de interop para las proyecciones de Task y la cancelación. Se considera terminado cuando las APIs exponen métodos utilizables basados en Task, o cuando se proporciona y verifica un patrón de helper oficial para estas llamadas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Android framework version

net10.0-android

Affected platform version

.NET 10 / Xamarin.AndroidX.Health.Connect.ConnectClient 1.1.0.2

Description

The AndroidX Health Connect binding exposes Kotlin suspend APIs as methods that require passing a raw Kotlin.Coroutines.IContinuation.

Example from the binding:

client.PermissionController.GetGrantedPermissions(IContinuation continuation)
client.ReadRecords(ReadRecordsRequest request, IContinuation continuation)

This is technically callable, but difficult to use correctly from .NET. A .NET consumer has to hand-write a coroutine bridge using TaskCompletionSource, detect IntrinsicsKt.COROUTINE_SUSPENDED, implement IContinuation, unwrap Kotlin Result.Failure, map Java exceptions into CLR exceptions, and optionally bridge cancellation.

For .NET consumers, these APIs should ideally be projected as Task / Task methods.

Current required workaround:

static Task<T> Await<T>(Func<IContinuation, object> action, CancellationToken cancelToken)
{
    var continuation = new Continuation<T>(cancelToken);
    var result = action(continuation);
    if (result != IntrinsicsKt.COROUTINE_SUSPENDED) { continuation.SetResult(result); }
    return continuation.Task;
}

sealed class Continuation<T> : Java.Lang.Object, IContinuation
{
    readonly TaskCompletionSource<T> tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
    readonly CancellationTokenRegistration ctr;

    public Continuation(CancellationToken cancelToken) =>
        ctr = cancelToken.Register(() => tcs.TrySetCanceled(cancelToken));

    public Task<T> Task => tcs.Task;
    public ICoroutineContext Context => EmptyCoroutineContext.Instance;

    public void ResumeWith(Java.Lang.Object result) => SetResult(result);

    public void SetResult(object result)
    {
        if (result is Java.Lang.Object { Class.Name: "kotlin.Result$Failure" } failure)
        {
            var field = failure.Class.GetDeclaredField("exception");
            field.Accessible = true;
            tcs.TrySetException(new Exception(field.Get(failure).ToString()));
        }
        else { tcs.TrySetResult((T)result); }

        ctr.Dispose();
    }
}

Expected behavior:
Kotlin suspend APIs should have generated .NET-friendly overloads such as:

Task<ICollection<string>> GetGrantedPermissionsAsync(CancellationToken cancellationToken = default);
Task<ReadRecordsResponse> ReadRecordsAsync(ReadRecordsRequest request, CancellationToken cancellationToken = default);

Actual behavior:
Only the raw continuation-based API is exposed.

Relevant official documentation:
Google’s Health Connect APIs are documented as Kotlin suspend functions. For example:
https://developer.android.com/reference/kotlin/androidx/health/connect/client/HealthConnectClient#readRecords(androidx.health.connect.client.request.ReadRecordsRequest)

Steps to Reproduce:

  1. Create a .NET Android project targeting net10.0-android36.0.
  2. Add Xamarin.AndroidX.Health.Connect.ConnectClient version 1.1.0.2.
  3. Try to call Health Connect suspend APIs such as GetGrantedPermissions or ReadRecords.
  4. Observe that the API requires IContinuation instead of returning Task.

Workaround:
Manually implement an IContinuation bridge with TaskCompletionSource, detect COROUTINE_SUSPENDED, unwrap kotlin.Result$Failure, and map the Java throwable to a CLR Exception.

Request:
Please consider projecting Kotlin suspend APIs in bound AndroidX packages as Task / Task methods, or provide an official helper/interop pattern for consuming suspend APIs from .NET.

Relevant log output

Lenguaje dominante
C#
Estrellas
319
Forks
73
Merge medio
2 d 22 h
PR fusionados (30 d)
6

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de dotnet/android-libraries

Todos los issues de dotnet/android-libraries

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.