I have one scenario where I need to perform search operation from database and show result on webpage. User have webform to type & search food from Sql Server
Database. So here I want to cancel previous ongoing search operation and continue with new search.
For e.g. first User type tea and request sent to Mvc ActionResult
using Ajax
. So now request is in process and user type Tea with milk so at that time I want to cancel previous request and continue with new request.
I have below Jquery
code to send request to Mvc ActionResult
with abort()
functionality.
var xhr = null;
function searchFood(o, q, f) {
if(xhr && xhr.readyState != 4){
console.log(xhr);
xhr.abort();
}
xhr = $.ajax({
type: "GET",
url: "/food/foodsearch/",
data: {
o: o,
q: q,
filters: f
},
beforeSend: function () {
showSpinner();
},
success: function (a) {
try {
xhr = null;
} catch (c) {
xhr = null;
}
},
error: function (a, b, c) {
xhr = null;
},
});
}
When user finish typing I call this searchfood
method. Take a look at my server side c#
code
[HttpGet]
[AjaxOnly]
public async Task<PartialViewResult> foodsearch(int o, string q, string filters, CancellationToken cancellationToken)
{
CancellationToken disconnectedToken = Response.ClientDisconnectedToken;
var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken);
//some local veriable declared
model.foods = filters.ToLower() == FoodFilterTypes.b_food || filters.ToLower() == all_categories ? await SearchFoodAsync(o, maxLimit, FoodModel.b_food, q, null, null, source.Token) : new List<Food>();
}
/// <summary>
/// search foods
/// </summary>
/// <param name="offset"></param>
/// <param name="limit"></param>
/// <param name="q"></param>
/// <param name="filters"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[NonAction]
protected async Task<List<Food>> SearchFoodAsync(int offset, int limit, string filters, string q, CancellationToken cancellationToken)
{
DataTable dtblFood = await LSocialBL.SearchFoodAsync(offset, limit, filters, q, cancellationToken);
//--- few more code lines
if (dtblFood != null)
{
foods = dtblFood.ToList<Food>();
//dispose object
dtblFood.Dispose();
dtblFood = null;
Parallel.ForEach(foods, new ParallelOptions { CancellationToken = cancellationToken }, async (f) =>
{
f.images = await GetFoodImagesAsync(f.id, cancellationToken);
});
//for (int i = 0; i < foods.Count; i++)
//{
// foods[i].images = await GetFoodImagesAsync(foods[i].id);
//}
}
}
Here my LSocialBL.SearchFoodAsync
method execute database operation like below.
I am executing stored procedure to fetch results.
using (IDataReader drdFood = await objSqlDatabase.ExecuteReaderAsync(objSqlCommand, cancellationToken))
{
dtblFoods.Load(drdFood);
}
return dtblFoods;
Here I am sending cancellationtoken to cancel existing db operation. It is necessary for me to cancel db operation as I have huge data of foods. I debug client request and it shows like below
I think this is really simple scenario so I have searched a lot for this but didn't find any useful links or examples. I found this but I am not getting how this implementation help me to cancel db operations or cancel previous old request. Can someone help me to workout this?