Search code examples
c#winformslinqasync-awaitentity-framework-4

Async task method issue on a linq query return in c#


I need help here with async tasks I am trying to return a list of values coming from a database and I have a table repository and then using a irepository of that class, the issue I am having is using my async task in my method to return the list of values.

Here is my code, my problem here is how to properly use the async tasks and then the await in the return for my linq query in the method because I get an error GetMaterialLookupCodeQuery()

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BarcodeReceivingApp.Core.Repositories;
using System.Data.Entity;

namespace BarcodeReceivingApp.Persistence.Repositories
{
    public class MaterialRepository : Repository<Material>, IMaterialRepository
    {
        public MaterialRepository(BarcodeReceivingDbContext context)
            : base(context)
        {

        }
        public async Task<IEnumerable<string>> GetMaterialLookupCodeQuery()
        {
            return await BarcodeReceivingDbContext.Materials.Include(m => m.MaterialLookupCode).Select(m => m.MaterialLookupCode);
        }

        public BarcodeReceivingDbContext BarcodeReceivingDbContext
        {
            get { return Context as BarcodeReceivingDbContext; }
        }
    }
}

Here is the interface of the class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BarcodeReceivingApp.Core.Repositories
{
    public interface IMaterialRepository : IRepository<Material>
    {
        Task<IEnumerable<string>> GetMaterialLookupCodeQuery();
    }
}

Solution

  • Linq uses the keyword yield return and this denotes that we won't actually do the operation until it's called upon. So your avoid code is trying to await the operation of a lazily invoked method.

    per this MSDN

    Although it's less code, take care when mixing LINQ with asynchronous code. Because LINQ uses deferred (lazy) execution, async calls won't happen immediately as they do in a foreach() loop unless you force the generated sequence to iterate with a call to .ToList() or .ToArray().

    So, lose the wait. You're not actually executing the statement until the results are used