Project Kotlin suspend APIs as Task<T> instead of raw IContinuation
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 45/100
Hướng nghiên cứu
Tái hiện sự cố với Xamarin.AndroidX.Health.Connect.ConnectClient 1.1.0.2 bằng cách sử dụng GetGrantedPermissions và ReadRecords, sau đó kiểm tra cách các Kotlin suspend APIs này được tạo trong binding. Kiểm tra hỗ trợ hiện có của generator hoặc interop cho các phép chiếu Task và việc hủy. Được xem là hoàn tất khi các APIs cung cấp các phương thức dựa trên Task có thể sử dụng, hoặc một mẫu helper chính thức được cung cấp và xác minh cho các lời gọi này.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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:
- Create a .NET Android project targeting net10.0-android36.0.
- Add Xamarin.AndroidX.Health.Connect.ConnectClient version 1.1.0.2.
- Try to call Health Connect suspend APIs such as GetGrantedPermissions or ReadRecords.
- 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
- Ngôn ngữ chính
- C#
- Star
- 319
- Fork
- 73
- Merge trung bình
- 2 ngày 22 giờ
- Pull request đã merge (30 ngày)
- 6
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của dotnet/android-libraries
-
Stable Updates 20261026Có thể đã có người làm @jonathanpeppers đã nhận 3 ngày trước. Đang mở
dotnet/android-libraries#1567 · 1 reaction · 2 người được giao ·
-
Unfreeze Xamarin.Firebase.Firestore and Xamarin.Protobuf.JavaLite now that Firebase BoM 35.0.0 fixes the Protolite conflictCó thể đã có người làm @jonathanpeppers đã nhận 15 ngày trước. Đang mở
dotnet/android-libraries#1563 · 1 reaction · 2 người được giao ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 20/100
dotnet/android-libraries#1561 · 4 bình luận ·
-
Regression: incorrect nullability annotations in Xamarin.AndroidX.AppCompat 1.8.0Có thể đã có người làm @jonathanpeppers đã nhận 18 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 40/100
dotnet/android-libraries#1558 · 2 bình luận · 2 reaction · 2 người được giao ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 68/100
dotnet/android-libraries#1549 ·
Tất cả issue của dotnet/android-libraries
Issue tương tự
-
[Bug] Dashboard renders attachment links that resolve to 404 when the FILES binding is absentĐang mởbug 優先: 低
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
-
.NET area: storage bug good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Larson-Logan/medal-sync#61 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area-ai bug untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
dotnet/extensions#7893 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 72/100