1

このシナリオで何を使用すればよいかわかりません。

基本的にこれを行うasp.net Web APIメソッドがあります

  1. ユーザーの近くにあるフォースクエアから興味のあるポイントを見つけます。
  2. フォースクエアの場所を使用してデータベースでクエリを実行し、ユーザーの近くの関心のあるポイントに関する一意のデータを見つけます。

ただし、フォースクエア情報の一部を保存して、その場所への独自のデータにリンクする必要があるため、すべての情報をデータベースに保存し、データベースをキャッシュ システムとして機能させることにしました。

これは、入ってきた新しいポイントをデータベースに挿入し、存在するかどうかを確認し、存在する場合はスキップするか、存在する場合は最後の更新日を確認する必要があることを意味します (フォースクエア ポリシーでは、すべてのデータを 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);
    }
}

編集 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

編集 2 Restsharp のラッパーを作成する方法を示すこの投稿 を見つけました。それは私が望んでいるものではありませんが、それは別の問題です.

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と思いますが、同時に行く必要があります。allStoresPointsOfInterestNearUserFindProduct

編集 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;
    }

編集 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;
     }
4

1 に答える 1

4

asyncこれには/を使用することをお勧めしawaitます。キャッシュの更新は、ASP.NET 要求から早期に戻ることが許容されるまれな状況の 1 つです。役立つコードについては、この件に関する私のブログ投稿をご覧ください。

したがって、次のようなものです(場所ごとに1つの「興味深い場所」を検索するように単純化されています):

public async Task<PlaceWithData> FindPlaceAsync(Location myLocation)
{
  Place place = await GetPlaceFromFoursquareAsync(myLocation);
  PlaceWithData ret = await GetExtraDataFromDatabaseAsync(place);
  if (ret.NeedsRefresh)
    BackgroundTaskManager.Run(() => UpdateDatabaseAsync(place, ret));
  return ret;
}

「独自のロール」キャッシュを実行するのではなく、ASP.NET キャッシュ システムを拡張することを検討することもできます。

于 2013-05-17T22:49:28.073 に答える