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



请考虑以下接口示例:

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将立即在同一线程上返回。与尽可能使用同步方法(和不同的接口)相比,使用此方法是否没有开销?即使大多数服务调用最终都是同步实现?

我已将Task<T>方法替换为新的 C# 7 ValueTask<T>类型:

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

这减少了任务返回同步结果时的开销。

与其

Task.FromResult(obj),我建议使该方法异步并仅返回 obj。 这样就不需要以任何方式调用任务计划程序。

这是完整的方法。

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;
    }
}

最新更新