We're in the process of refactoring all, or a large portion of our .NET 4.6 MVC WebAPI controller methods to async
methods.
This seems like it will work well for methods that have a lower level invocation of a method that is awaitable such as SQL command execution; however we are utilizing an in-memory distributed caching framework by Alachisoft called NCache (4.6 SP2 to be exact), which does not offer any truly asynchronous methods.
Would it be worth creating an async
helper method that would expose a awaitable Task<object>
return type?
Traditionally using the NCache API, you Get
an object from cache by a Key
in the following usage;
NCacheObject.Get(string);
The proposal is to create a helper method of the following;
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);
}
So that it would then allow full waterfall of async
methods up to the entry controller method as such;
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");
}
And finally the controller method;
[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;
}
This would complicate the refactoring, as the original methods actually had output parameters for bool success
and string message
; but it seems this can be accomplished in a decent and quick manner using a Tuple<>
; otherwise we could just create a return type model.
To do this properly, there would be many hundreds of methods to refactor; quite an undertaking.
- Would this work as expected, and be the best solution to accomplish the objective?
- Is it likely worth all of the effort required, with the end goal of increasing scalability and subsequently "performance" of the web servers?