为NCache Get实现Awaitable Async方法

时间:2016-09-15 20:48:46

标签: c# asynchronous async-await ncache

我们正在将所有或大部分.NET 4.6 MVC WebAPI控制器方法重构为async方法。

对于具有较低级别调用等待方法(如SQL命令执行)的方法,这似乎很有效;但是我们正在使用Alachisoft的内存分布式缓存框架,名为NCache(确切地说是4.6 SP2),它不提供任何真正的异步方法。

是否值得创建一个async辅助方法,以便公开一个等待的Task<object>返回类型?

传统上使用NCache API,在以下用法中Get Key来自缓存的对象;

NCacheObject.Get(string);

建议是创建以下的辅助方法;

protected static async Task<Object> GetAsync(string key, Cache nCache)
{
    Task<Object> getTask = new Task<Object>(() => nCache.Get(key));
    getTask.Start();
    return await getTask.ConfigureAwait(false);
}

这样它就可以允许async方法的完全瀑布直到入口控制器方法;

public static async Task<Tuple<List<SomeModel>, bool, string>> GetSomeModelList(string apiKey)
{
    return newTuple<List<SomeModel>, bool, string>(await GetAsync("GetSomeModelKey", CacheInstance).ConfigureAwait(false), true, "Success message");
}

最后是控制器方法;

[HttpGet, Route("Route/Method")]
public async Task<ResponseOutputModel<List<SomeModel>>> GetSomeModelList()
{
    ResponseOutputModel<List<SomeModel>> resp = new ResponseOutputModel<List<SomeModel>>();

    try
    {
        Tuple<List<SomeModel>, Boolean, String> asyncResp = await CacheProcessing.GetSomeModelList(GetApiKey()).ConfigureAwait(false);

        resp.Response = asyncResp.Item1;
        resp.Success = asyncResp.Item2;
        resp.Message = asyncResp.Item3;
    }
    catch (Exception ex)
    {
        LoggingHelper.Write(ex);
        resp.StatusCode = Enumerations.ApiResponseStatusCodes.ProcessingError;
        resp.Success = false;
        resp.Message = ex.Message;
    }

    return resp;
}

这会使重构变得复杂,因为原始方法实际上具有bool successstring message的输出参数;但似乎可以使用Tuple<>以体面和快捷的方式完成;否则我们可以创建一个返回类型模型。

为了做到这一点,将有数百种重构方法;很有希望。

  1. 这是否符合预期,是实现目标的最佳解决方案?
  2. 可能值得所有努力,最终目标是提高可扩展性,随后提高性能&#34;网络服务器?

2 个答案:

答案 0 :(得分:4)

  

是否值得创建一个异步帮助方法来公开一个等待的任务返回类型?

Nope

  

建议是创建以下

的帮助方法

这只是将内存中的工作排入队列。

(旁注:永远不应该使用任务构造函数。永远。如果需要将工作排队到线程池,请使用Task.Run而不是Start的任务构造函数

  

这是否符合预期,是实现目标的最佳解决方案?

     

是否值得花费所有必要的努力,最终目标是提高Web服务器的可扩展性和随后的“性能”?

这些都是同一个问题。目标是可扩展性;异步只是帮助你完成它的一种方法。

Asynchrony协助ASP.NET的可伸缩性,因为它释放了一个可以处理其他请求的线程。但是,如果您通过使用另一个线程来创建异步的方法,那么这根本不会对您有所帮助。我将此称为“假异步” - 这些方法看起来是异步的,但它们实际上只是在线程池上同步运行。

与真正的异步相比,虚假异步实际上会损害您的可扩展性。

答案 1 :(得分:1)

因为这是一个内存缓存,我说这是对NCache的任何直接经验,但与其他缓存系统的经验。

  1. 是的,这当然会奏效。我宁愿选择一个响应结构或一个通用类,它允许我定义我的响应类型(如果可能的话)。元组并不坏,如果你选择课程,可能会更高效。但是他们的眼睛并不容易。
  2. 现在,谈到表现时,有一个问题。这是一个缓存服务器,当然你想要快速读写。访问内存缓存应该很容易。当你在这里直接访问内存时,从性能的角度来看,它并不会真正给你带来太多帮助。您是否确保您的代码完全异步并且您正在使用线程池来使事情变得更好?是的,当然,但是当你访问缓存时,它所做的只是添加一个额外的层或工作。
  3. 当您要进行异步时,请确保您的内存缓存是线程安全的。 :)