Я не уверен, что использовать в этом сценарии.Что я должен здесь использовать? Threading? Асинхронный?
У меня есть метод asp.net Web API, который в основном делает это
- Находит точку интересов от четыреугольного вблизи пользователя.
- Использует места расположения четырехквартирных домов, чтобы делать запросы в моей базе данных, чтобы найти уникальные данные о достопримечательностях рядом с пользователем.
Однако, поскольку мне нужно сохранить некоторые данные из четырех источников для ссылки на мои уникальные данные в этом месте, я решил сохранить всю информацию в моей базе данных и заставить мою базу данных действовать как моя система кеширования.
Это означает что-то новое, что приходит в меня, я должен вставить в свою базу данных, проверить, существует ли она, и если да, то пропустите ее или если она существует, проверьте последнюю дату обновления (в соответствии с условиями четырехсоставной политики все данные должны быть обновлены после 30 дней), и если он закончил дату обновления, я должен обновить данные.
Я хочу замедлить пользователя и ждать, пока это произойдет. Я хочу, чтобы мой код выполнял шаг 1, а затем выполнял то, что я только что упомянул, в то же время делая шаг 2.
После завершения этапа 2 я хочу вернуть данные и позволить пользователю встать на пути. Если моя система кеширования не завершена, она должна продолжать идти, но не болота пользователя.
Я не буду использовать какие-либо из этих новых результатов на шаге 2, как если бы я их вставлял, тогда я не буду иметь данных в этом месте в это время.
Не уверен, что мне нужно создать поток или использовать async/await для достижения этого.
Редактировать
Вот что я пытаюсь сделать
public HttpResponseMessage Get()
{
// this will do a foursquare lookup to find all stores near the user
// I want to insert them into my database and link it to my unquie data.
// stores pulled from foursquare will
// a) Be new and not in my database
// b) exist in my database but have been refreshed lately
// c) have not been refreshed in timeframe of foursquare policy
// THIS SHOULD WORK IN THE BACKGROUND
storeService.PointsOfInterestNearUser(80, -130); //As you can see it is
//void. Not sure where to put the async/await stuff
// find this product. Should be happening at the same time as above line.
var product = productService.FindProduct("Noodles");
//This will get returned to the user.
// the new stores taht are being added in StoreNearUser
//won't effect this search as I will have not data on this new store
// if existing store is being refreshed it is possible old
//address might be picked up...
//I can live with that as I doubt the address will change much.
// this should happen after product
var allStores = storeService.FindStoresThatHaveItem(product);
// this should be returned as soon as above line is finished.
//If StoreNearUser is not done, it should keep going but not hold up user.
return allStores;
}
public void StoresNearUser(double latitude, double longitude)
{
// get all categories I can about in foursquare.
//First time from db otherwise cached.
List<StoreCategory> storeCategories = GetStoreCategories();
// do a request and get everything in near the user
//(provided it is also in a category I care about)
var request = CreateFoursquareStoreRequest
(latitude, longitude, storeCategories);
// do the actual call.
var response = client.Execute<VenueSearch>(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// start going through the results, add or update or skip of entry will happen
AddUpdateStores(storeCategories, response);
}
else
{
ErrorSignal.FromCurrentContext().Raise(response.ErrorException);
}
}
Edit 2
public async Task StoresNearUser(double latitude, double longitude)
{
// get all categories I can about in foursquare. First time from db otherwise cached.
List<StoreCategory> storeCategories = GetStoreCategories();
// do a request and get everything in near the user(provided it is also in a category I care about)
var request = CreateFoursquareStoreRequest(latitude, longitude, storeCategories);
await client.ExecuteAsync<VenueSearch>
( request
, response =>
{
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
AddUpdateStores(storeCategories, response);
}
else
{
ErrorSignal.FromCurrentContext()
.Raise(response.ErrorException);
}
}
);
}
дает мне эту ошибку
Cannot await 'RestSharp.RestRequestAsyncHandle'
Я также не получаю разницу между Task
и void
. Из того, что я прочитал, если вы просто используете Task
, это означает, что вы ничего не отправляете обратно в смысл, то почему бы просто не использовать void
?
Edit 2 Я нашел this post, чтобы показать мне, как сделать обертку для Restsharp. Это не 100%, что я хочу, но это отдельная проблема.
public async Task StoresNearUser(double latitude, double longitude)
{
List<StoreCategory> storeCategories = GetStoreCategories();
var request = CreateFoursquareStoreRequest
(latitude, longitude, maxRadius, returnLimit, storeCategories);
var response = await client.GetResponseAsync(request);
if (response.StatusCode == HttpStatusCode.OK)
{
// had to use json.net right now as the wrapper does not expose restsharps deserilizer
var venue = JsonConvert
.DeserializeObject<VenueSearch>(response.Content);
AddUpdateStores(storeCategories, venue);
}
else
{
ErrorSignal.FromCurrentContext()
.Raise(response.ErrorException);
}
}
public async Task<HttpResponseMessage>Get()
{
await storeService.PointsOfInterestNearUser(80, -130);
var product = productService.FindProduct("Noodles");
var allStores = storeService.FindStoresThatHaveItem(product);
return allStores;
}
Когда я смотрю из отладчика, похоже, что все идет полным ходом. Я думаю, product
и allStores
должны быть, так как мне нужен продукт, прежде чем я смогу найти магазины, но PointsOfInterestNearUser
должен идти в то же время, что и FindProduct
.
Редактировать 3 Вот мой метод FindProduct. Не уверен, что делать асинхронно для меня, похоже, все должно подождать.
public ResponseResult<Product> FindProduct(string barcode)
{
ResponseResult<Product> responseResult = new ResponseResult<Product>();
Product product = null;
try
{
var findBarCode = context.Barcodes.Where(x => x.Code == barcode).Select(x => x.Product).FirstOrDefault();
responseResult.Response = product;
if (product == null)
{
responseResult.Status.Code = HttpStatusCode.NotFound;
}
else
{
responseResult.Status.Code = HttpStatusCode.OK;
}
}
catch (SqlException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
responseResult.Status.Code = HttpStatusCode.InternalServerError;
responseResult.Status.Message = GenericErrors.InternalError;
}
return responseResult;
}
Edit 4
Все еще не уверены, как сделать Task.WhenAll()
public async Task<HttpResponseMessage>Get()
{
Task[] tasks = new Task[2];
tasks[0] = storeService.PointsOfInterestNearUser(80, -130);
tasks[1] = productService.FindProduct("Noodles");
await Task.WhenAll(tasks);
// not sure how to get product back out. I looked in the debugger and saw a "Result" that has it but when I do tasks[1].Result inetllisene cannot find .Result
var allStores = storeService.FindStoresThatHaveItem(product);
return allStores;
}
Похоже, что нить будет работать лучше всего. Если вы не заботитесь о возвращенной информации из вызова для обновления db, зачем использовать async/wait? Можете ли вы просто стрелять и забыть? – Jras
@KirkWoll: Совсем нет. 'async' и' await' не подразумевают многопоточность. –
@ Stephen, это правда, я забыл, что все это может произойти в той же теме. К сожалению. –