为内存中的数据列表实现异步接口

时间:2018-10-26 14:53:21

标签: c# asynchronous interface

我目前正在将同步实现更改为异步实现。我已经更新并定义了以下接口:

public interface IMGP1DFC
{
    // get all
    Task<IEnumerable<MGP1DFC>> GetAllAsync();

    // get single
    Task<MGP1DFC> GetSingleAsync(int id);

    // add
    void Add(MGP1DFC mgp1dfc);

    // update
    void Update(MGP1DFC mgp1dfc);

    // delete
    void Delete(MGP1DFC mgp1dfc);

    // save
    Task SaveAsync();
}

我有一个使用此接口实现和定义的服务,该接口连接到这样的数据库:

public class MGP1DFCData : IMGP1DFC
{
    private ApplicationDbContext _applicationDbContext;
    //
    public MGP1DFCData(ApplicationDbContext applicationDbContext) {
        _applicationDbContext = applicationDbContext;
    }
    public void Add(MGP1DFC mgp1dfc)
    {
        _applicationDbContext.Add(mgp1dfc);
    }

    public void Delete(MGP1DFC mgp1dfc)
    {
        _applicationDbContext.Remove(mgp1dfc);
    }

    public async Task<IEnumerable<MGP1DFC>> GetAllAsync()
    {
        return await _applicationDbContext.MGP1DFC.OrderBy(x => x.ReceivedByDateTime).ToListAsync();
    }

    public async Task<MGP1DFC> GetSingleAsync(int id)
    {
        return await _applicationDbContext.MGP1DFC.FirstOrDefaultAsync(x => x.Id == id);
    }

    public async Task SaveAsync()
    {
        await _applicationDbContext.SaveChangesAsync();
    }

    public void Update(MGP1DFC mgp1dfc)
    {
        _applicationDbContext.Update(mgp1dfc);
    }
}

没问题。

但是,以前这里有一个内存服务:

public class MGP1DFCInMemory : IMGP1DFC
{

    List<MGP1DFC> MGP1DFCs;

    public MGP1DFCInMemory()
    {
        MGP1DFCs = new List<MGP1DFC> {
            new MGP1DFC { Id = 1, Name = "DS", Nino = "DS123123D", SentByName = "Bobbleton", SentByEmail = "Bobbleton@ds.com.uk.net", ReceivedByDateTime = DateTime.Now},
            new MGP1DFC { Id = 2, Name = "Kenneth", Nino = "FG123123D", SentByName = "Pattie", SentByEmail = "pattie@ds.com.uk.net", ReceivedByDateTime = DateTime.Now.AddHours(6)},
            new MGP1DFC { Id = 3, Name = "Bob", Nino = "DS123123D", SentByName = "The Chieftain", SentByEmail = "cheiftain@ds.com.uk.net", ReceivedByDateTime = DateTime.Now.AddMinutes(904)}
        };
    }

    public void Add(MGP1DFC MGP1DFC)
    {
        MGP1DFC.Id = MGP1DFCs.Max(index => index.Id) + 1;
        MGP1DFCs.Add(MGP1DFC);
    }

    public void Delete(MGP1DFC MGP1DFC)
    {
        MGP1DFCs.Remove(MGP1DFC);
    }

    public IEnumerable<MGP1DFC> GetAll()
    {
        return MGP1DFCs.OrderBy(x => x.ReceivedByDateTime);
    }

    public MGP1DFC GetSingle(int id)
    {
        return MGP1DFCs.FirstOrDefault(x => x.Id == id);
    }

    public MGP1DFC Update(MGP1DFC category)
    {
        MGP1DFC formToUpdate = MGP1DFCs.FirstOrDefault(i => i.Id == category.Id);
        formToUpdate.CompletedByDateTime = DateTime.Now;
        formToUpdate.CompletedByEmail = "ds@ds.com";
        formToUpdate.CompletedBy = "DS";
        return formToUpdate;
    }
}

我可以实现异步内存服务吗?

例如

public async Task<IEnumerable<MGP1DFC>> GetAllAsync()
    {
        return await MGP1DFCs.OrderBy(x => x.ReceivedByDateTime).ToListAsync();
    }

还是尝试,这完全是浪费时间!?

2 个答案:

答案 0 :(得分:1)

如果只需要该类简单地实现接口,则可以使用Task.FromResult编写此接口的同步实现。这将创建已经完成的任务,并且所有操作均同步

public Task<IEnumerable<MGP1DFC>> GetAllAsync()
{
    return Task.FromResult(MGP1DFCs);
}

public Task<MGP1DFC> GetSingleAsync(int id)
{
    return Task.FromResult(MGP1DFCs.FirstOrDefault(x => x.Id == id));
}

public async Task SaveAsync()
{
    // Not much to do here...
    return Task.CompletedTask;
} 

答案 1 :(得分:1)

“内存服务”没有任何异步,假设它(顾名思义)仅对内存数据执行CPU绑定的工作。

为实际上是同步的方法提供异步包装通常被认为是代码异味。有关更多信息,请参考@Stephen Cleary's blog post

编辑:如果“ in memory service”只是与数据库通信的真正异步服务的某种存根,而您只是希望它实现与“ real”相同的接口服务,您可以使用Task.FromResult方法返回@FCin建议的已完成任务。如果“内存中的服务”是别的,那么实现“异步”接口就没有多大意义。