Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ConfiguredCancelableAsyncEnumerable<T> to IAsyncEnumerable<T>? #115328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mariusz96 opened this issue May 6, 2025 · 1 comment
Closed

ConfiguredCancelableAsyncEnumerable<T> to IAsyncEnumerable<T>? #115328

mariusz96 opened this issue May 6, 2025 · 1 comment
Labels
needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners

Comments

@mariusz96
Copy link

mariusz96 commented May 6, 2025

This class works fine:

public interface IMyService
{
    Task<IAsyncEnumerable<Order>> GetOrdersInUserCity(int userId);
}

public class MyService(MyContext myContext) : IMyService
{
    public async Task<IAsyncEnumerable<Order>> GetOrdersInUserCity(int userId)
    {
       var auxiliaryData = await myContext.Users.FirstAsync(x => x.UserId == userId);
       return myContext.Orders.Where(x => x.CityId == auxiliaryData.CityId).AsAsyncEnumerable();
    }
}

But if I try to add a cancellation token it ceases to compile because of CS0029 (Cannot implicitly convert ConfiguredCancelableAsyncEnumerable to IAsyncEnumerable):

public interface IMyService
{
    Task<IAsyncEnumerable<Order>> GetOrdersInUserCity(int userId, CancellationToken cancellationToken);
}

public class MyService(MyContext myContext) : IMyService
{
    public async Task<IAsyncEnumerable<Order>> GetOrdersInUserCity(int userId, CancellationToken cancellationToken)
    {
       var auxiliaryData = await myContext.Users.FirstAsync(x => x.UserId == userId, cancellationToken); // Compiles
       return myContext.Orders.Where(x => x.CityId == auxiliaryData.CityId).AsAsyncEnumerable().WithCancellationToken(cancellationToken); // Does not compile
    }
}

// EDIT: Should be:

// public interface IMyService
// {
//     IAsyncEnumerable<Order> GetOrdersInUserCity(int userId, CancellationToken cancellationToken); // No Task<>
// }

// public class MyService(MyContext myContext) : IMyService
// {
//     public async IAsyncEnumerable<Order> GetOrdersInUserCity(int userId, [EnumeratorCancellation] CancellationToken cancellationToken) // [EnumeratorCancellation] attribute
//     {
//         var auxiliaryData = await myContext.Users.FirstAsync(x => x.UserId == userId, cancellationToken);
//         await foreach (var order in myContext.Orders.Where(x => x.CityId == auxiliaryData.CityId).AsAsyncEnumerable().WithCancellationToken(cancellationToken)) // Iterator
//         {
//             yield return order;
//         }
//     }
// }

Pardon my ignorance, but how can I convert ConfiguredCancelableAsyncEnumerable back to IAsyncEnumerable? Is it 'not supposed' to be used this way😅?

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 6, 2025
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label May 6, 2025
@huoyaoyuan
Copy link
Member

Pardon my ignorance, but how can I convert ConfiguredCancelableAsyncEnumerable back to IAsyncEnumerable? Is it 'not supposed' to be used this way😅?

You can't. It's meant to be consumed directly (await foreach).

To create a new IAsyncEnumerable object with additional cancellation token, you need to use yield return with [EnumerationCancellation].

@stephentoub stephentoub closed this as not planned Won't fix, can't repro, duplicate, stale May 6, 2025
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label May 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners
Projects
None yet
Development

No branches or pull requests

3 participants