2013-12-09 3 views
1

클라이언트 (Windows CE 핸드 헬드 장치)의 98-lb- 약한 특성으로 인해 각 결과 집합을 작게 유지하기 위해 더 이상 데이터가 반환되지 않을 때까지 내 웹 API 메서드를 호출하기 위해)이 코드를 사용하고 있습니다 :conditon 동안 "placeholder"를 사용하지 않고 할 일이있을 때까지 안전하게 반복 할 수 있습니까?

while (moreRecordsExist) 
{ 
    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 (null == arr) 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 

이 (작동 내가 널 위해 WebResponse를을 체크하면) NullReferenceException이와 충돌하지만, 한 번에 도달하지 않습니다 나는, 내 while 루프처럼 정말하지 않습니다 moreRecordsExist는 false로 지정됩니다. 그래서, Resharper 사냥개를 느슨하게하여 더 좋은 제안이 있는지 확인했지만, "Expression is always true"라고 말하면서 그 라인에 "나와있는"수정을하는 것이 "while (사실) "

나는 그것이 많은 개선 방법을 보지 못했다.

더 똑똑한 구조로 같은 것을 달성 할 수있는 방법이 있습니까?

답변

1

false을 변수 moreRecordsExist에 할당 한 직후에 문을 사용하여 루프를 깨뜨릴 수 있습니다. 따라서 루프의 시작 부분에서 값이 false가되지 않습니다. 왜 응답 일부 메타 데이터를 반환하지

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

"there"= "their" –

+0

@ClayShannon 맞습니다. 큰 도움은 아니지만 적어도이 루프는 break 문으로 끝날 수 있다고 명시해야합니다. 코드를 읽는 누군가가 여분의 moreRecordsExist 변수를 추적 할 필요가 없습니다. 또한 매핑 부분을 자체 기능으로 이동하면 읽기 쉽습니다. –

1

, 예를 들면 : ReSharper에서 알 수 및 moreRecordsExist 변수의 제거로 당신은 변화를 만들 수 있습니다 {페이지 : 10}? 그렇다면 얼마나 많은 기록을 남겼는지 정확히 알 수 있습니다.

+0

추가 쿼리 문을 피하려고합니다. , 레코드 수를 반환하는 것이 필요합니다. –

1

do..while() 루프 사용을 고려하십시오. 이것은 "while-loop-is-never-reached"문제를 해결합니다 ... moreRecordsExist가 설정 되더라도 항상 적어도 한 번은 실행됩니다.

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

그냥 그 펑키를 뒤집지 않습니까? 이제 결국 Resharper가 위아래로 뛰어 오르고 소리를 질러 대며 "moreRecordsExists는 항상 사실입니다!" –

+0

네, 그게 정확히 무엇입니까; 그래서 나는 그것이 "do ... while"이 "while ... do"보다 바람직하다고 생각 하느냐에 따라 맛과 스타일의 문제라고 생각합니다. 제가 가치있는 일을한지 꽤 오래되었지만, 그것도 의견의 문제입니다 (아름다움을 보는 사람의 눈). –

관련 문제