在Task.Result中包装同步方法的开销

时间:2017-01-25 19:57:16

标签: c# .net async-await

请考虑以下界面示例:

public interface ISomeAsyncService<T>
{
    Task<T> GetSomeObjectAsync(string id);
}

现在让我们假设这个接口的一些实现确实从数据存储中异步检索对象。 但是,此服务的其他实现可能会将对象存储在内存中,例如:

public class SomeService : ISomeAsyncService<MyObject>
{
    private static Dictionary<string, MyObject> _dictionary = new Dictionary<string, MyObject>();
    public Task<MyObject> GetSomeObjectAsync(string id)
    {
        var obj = _dictionary[id];
        return Task.FromResult(obj);
    }
}

我这样做是为了能够为同步和异步服务使用相同的接口。目前尚不清楚哪些服务实现将使用静态内存对象,哪些将从数据存储中检索。

根据我的理解,Task.FromResult将立即在同一个线程上返回。 使用这种方法是否没有开销,而不是尽可能使用同步方法(和不同的接口)?即使大多数服务调用最终都要进行同步实现吗?

2 个答案:

答案 0 :(得分:0)

我已使用新的C#7 ValueTask<T> type替换了我的Task<T>方法:

public interface ISomeAsyncService<T>
{
    ValueTask<T> GetSomeObjectAsync(string id);
}

这可以减少Task返回同步结果时的开销。

答案 1 :(得分:-3)

而不是Task.FromResult(obj)我建议将方法设为异步并返回obj。这样就不需要以任何方式调用TaskScheduler。

这是完整的方法。

public class SomeService : ISomeAsyncService<MyObject>
{
    private static Dictionary<string, MyObject> _dictionary = new Dictionary<string, MyObject>();
    public async Task<MyObject> GetSomeObjectAsync(string id)
    {
        var obj = _dictionary["id"];
        return obj;
    }
}