How can I safely loop until there is nothing more to do without using a “placeholder” while conditon?

后端 未结 3 716
名媛妹妹
名媛妹妹 2021-01-23 16:47

In order to call my Web API method until no more data is returned (I\'m fetching it in batches, to keep each result set small, due to the 98-lb-weakling persona of the client (W

相关标签:
3条回答
  • 2021-01-23 17:12

    Consider using a do..while() loop. This gets you around the "while-loop-is-never-reached" problem... it will always run at least once, no matter what moreRecordsExist is set to.

    do
    {
        redemptionsList.redemptions.Clear();
        string uri = String.Format("http://platypus:28642/api/Redemptions/{0}/{1}",     lastIdFetched, RECORDS_TO_FETCH);
        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        webRequest.Method = "GET";
    
        using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
        {
            if (webResponse.StatusCode == HttpStatusCode.OK)
            {
                var reader = new StreamReader(webResponse.GetResponseStream());
                string s = reader.ReadToEnd();
                var arr = JsonConvert.DeserializeObject<JArray>(s);
                if (arr == null) break;
    
                foreach (JObject obj in arr)
                {
                    id = obj.Value<int?>("Id") ?? 0;
                    var _redemptionId = obj.Value<string>("RedemptionId") ?? "";
                    var _redemptionItemId = obj.Value<string>("RedemptionItemId") ?? "";
                    var _redemptionName = obj.Value<string>("RedemptionName") ?? "";
                    double _redemptionAmount = obj.Value<double?>("RedemptionAmount") ?? 0.0;    
                    var _redemptionDept = obj.Value<string>("RedemptionDept") ?? "";
                    var _redemptionSubdept = obj.Value<string>("RedemptionSubDept") ?? "";
    
                    redemptionsList.redemptions.Add(new HHSUtils.Redemption
                    {
                        Id = id,
                        RedemptionId = _redemptionId,
                        RedemptionItemId = _redemptionItemId,
                        RedemptionName = _redemptionName,
                        RedemptionAmount = _redemptionAmount,
                        RedemptionDept = _redemptionDept,
                        RedemptionSubDept = _redemptionSubdept,
                    });
                } // foreach
            } // if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 2))
        } // using HttpWebResponse
        int recordsAdded = LocalDBUtils.BulkInsertRedemptions(redemptionsList.redemptions);
        totalRecordsAdded += recordsAdded;
        moreRecordsExist = (recordsToFetch > (totalRecordsAdded));
        lastIdFetched = id;
    } while (moreRecordsExist);
    
    0 讨论(0)
  • 2021-01-23 17:21

    You break out the loop with a break statement immediately after assigning false to moreRecordsExist variable, so its value will never be false in the beginning of the loop. You can make a change as ReSharper suggests and get rid of moreRecordsExist variable:

    while (true)
    {
        redemptionsList.redemptions.Clear();
        string uri = String.Format("http://platypus:28642/api/Redemptions/{0}/{1}", lastIdFetched, RECORDS_TO_FETCH);
        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        webRequest.Method = "GET";
    
        using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
        {
            if (webResponse.StatusCode == HttpStatusCode.OK)
            {
                var reader = new StreamReader(webResponse.GetResponseStream());
                string s = reader.ReadToEnd();
                var arr = JsonConvert.DeserializeObject<JArray>(s);
                if (arr == null) break;
    
                foreach (JObject obj in arr)
                {
                    id = obj.Value<int?>("Id") ?? 0;
                    var _redemptionId = obj.Value<string>("RedemptionId") ?? "";
                    var _redemptionItemId = obj.Value<string>("RedemptionItemId") ?? "";
                    var _redemptionName = obj.Value<string>("RedemptionName") ?? "";
                    double _redemptionAmount = obj.Value<double?>("RedemptionAmount") ?? 0.0;
                    var _redemptionDept = obj.Value<string>("RedemptionDept") ?? "";
                    var _redemptionSubdept = obj.Value<string>("RedemptionSubDept") ?? "";
    
                    redemptionsList.redemptions.Add(new HHSUtils.Redemption
                    {
                        Id = id,
                        RedemptionId = _redemptionId,
                        RedemptionItemId = _redemptionItemId,
                        RedemptionName = _redemptionName,
                        RedemptionAmount = _redemptionAmount,
                        RedemptionDept = _redemptionDept,
                        RedemptionSubDept = _redemptionSubdept,
                    });
                } // foreach
            } // if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 2))
        } // using HttpWebResponse
        int recordsAdded = LocalDBUtils.BulkInsertRedemptions(redemptionsList.redemptions);
        totalRecordsAdded += recordsAdded;
        //moreRecordsExist = (recordsToFetch > (totalRecordsAdded));
        lastIdFetched = id;
    } // while
    
    0 讨论(0)
  • 2021-01-23 17:32

    Why not return some metadata with response, e.g. {Pages:10} ? Then you know exactly how many records you're going after.

    0 讨论(0)
提交回复
热议问题