【问题标题】:Implement Async Interface synchronous [duplicate]实现异步接口同步[重复]
【发布时间】:2016-01-01 03:40:02
【问题描述】:

假设我有以下界面:

public interface IApiOutputCache
{
    Task RemoveStartsWithAsync(string key);
    Task<T> Get<T>(string key) where T : class;
    Task RemoveAsync(string key);
    Task<bool> ContainsAsync(string key);
    Task Add(string key, object o, DateTimeOffset expiration, params string[] dependsOnKeys);
    Task<IEnumerable<string>> GetAllKeys();
}

我可以实现不同的缓存提供程序。我为两个不同的缓存实现了两次:

a) 天蓝色的 redis b) 内存缓存

对于 azure redis,这绝对可以正常工作,因为 StackExchange.Redis 为我提供了所有异步方法,因此我可以保持完全异步。

现在我为内存缓存实现了另一个,它不为我提供异步 api。 现在实现这个接口的最佳实践是什么? 按原样实施,但只同步所有内容?将内部调用扭曲到Task.Run(我认为对于快速内存缓存调用来说不是一个好主意)。

【问题讨论】:

  • 我同意你的建议。或者,您可以同步运行所有内容并返回 Task.FromResult 以使其看起来像异步。

标签: c# .net async-await task-parallel-library


【解决方案1】:

忘记Task.Run,无需将任何内容卸载到ThreadPool

同步实现所有内容,并在返回值时返回已完成的 TaskTask.FromResult,在不返回值时返回 Task.CompletedTask

Task<T> GetAsync<T>(string key)
{
    T result = Get(key);
    return Task.FromResult(result);
}

Task RemoveAsync(string key)
{
    Remove(key);
    return Task.CompletedTask;
}

甚至更好,因为它是一个缓存,您可以缓存任务本身而不是结果,并且每次都返回相同的任务对象。

【讨论】:

  • 谢谢。好吧,这就是我想的方式。但是什么是Task.CompletedTask?它是 .net 4.6 中的新功能,对吗?它与 Task.FromResult(0) 有何不同?
  • 是的,它是 .Net 4.6 中的新功能。它稍微好一点,因为它每次都返回相同的实例,而不是每次调用都分配一个新任务。 stackoverflow.com/a/26226195/885318
猜你喜欢
  • 2015-03-29
  • 2018-11-04
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多