我们正在将所有或大部分.NET 4.6MVC WebAPI控制器方法重构为async方法。
对于具有较低级别调用方法(如SQL命令执行)的方法,这似乎很有效;但是,我们使用的是一个名为NCache (确切地说是4.6SP2)的内存中分布式缓存框架,它没有提供任何真正的异步方法。
是否值得创建一个async助手方法来公开一个可访问的Task<object>返回类型?
传统上使用NCache API时,您可以使用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 success和string message的输出参数;但是,这似乎可以使用Tuple<>以一种体面和快速的方式完成;否则,我们就可以创建一个返回类型模型。
要正确地做到这一点,将有数百种方法来重构;这是一项相当大的任务。
发布于 2016-09-15 21:25:00
是否值得创建一个异步助手方法来公开一个awaitable返回类型?
不是。
建议创建以下帮助方法
这只是将内存中的工作排队到线程池。
(边注:不应使用任务构造函数。永远不会。如果您需要将工作排队到线程池,请使用Task.Run而不是带有Start的任务构造函数)
这是否如预期的那样起作用,并成为实现目标的最佳解决方案? 它是否值得付出所需的一切努力,最终目标是提高web服务器的可伸缩性和随后的“性能”?
这些都是同一个问题。目标是可伸缩性;异步只是帮助您完成它的一种方法。
异步有助于ASP.NET上的可伸缩性,因为它释放了一个可以处理其他请求的线程。但是,如果您通过使用另一个线程来创建异步方法,那么这根本无助于您。我称之为“假异步”--这类方法看起来是异步的,但它们实际上只是在线程池上同步运行。
与真异步不同,假异步实际上会损害您的可伸缩性。
发布于 2016-09-15 21:09:20
因为这是一个内存缓存,我这样说是出于对NCache的任何直接体验,而是对其他缓存系统的体验。
https://stackoverflow.com/questions/39520123
复制相似问题