나는 Bureau 또는 Meteorology에서 7 일간의 예측 데이터를 수집하고이를 웹 페이지에 표시하는 수업을 가지고 있습니다. 30 분마다 스크립트가 실행되어 국에서 업데이트 된 데이터를 가져옵니다.주어진 키가 사전에 없습니다. dictionary.ContainsKey ("given_key") == true
국은 머리글 행이있는 탭 구분 형식으로 데이터를 제공합니다. 모든 필드를 추출한 후 값을 구문 분석을 위해 Dictionary<string,string>
에 넣습니다. 분명한 이유로 데이터 구성을위한 중요한 필드는 "forecast_date"입니다. 따라서 구문 분석을 시작하기 전에 사전에 실제로이 키가 포함되어 있는지 확인합니다. 이것은 실제로 대부분의 작동
static object ForecastLockingObj= new object();
private void UpdateWeather()
{
if(isTimeForUpdate())
{
lock(ForecastLockingObj)
{
if(isTimeForUpdate())
{
Dictionary<string, string> ForecastData = Get7DayForecast();
int forecastDate = int.MinValue;
if (ForecastData.ContainsKey("forecast_date") && int.TryParse(ForecastData["forecast_date"], out forecastDate))
{
//Parse the data
SetNextUpdateTime();
}
}
}
}
}
:
는 여기에 내가 뭘하는지 매우 간단한 예입니다. 그러나 아주 가끔 나는 다음과 같은 예외를 얻을 수 있습니다 :
라인 (231) 다음 "forecast_date"의 존재를 확인하는 정수로 구문 분석을 시도하는 경우 문이[KeyNotFoundException: The given key was not present in the dictionary.]
System.ThrowHelper.ThrowKeyNotFoundException() +28
System.Collections.Generic.Dictionary`2.get_Item(TKey key) +7457036
CoA.WebUI.Controls.WeatherWidget.UpdateWeather() in C:\dev\WeatherWidget.cs:231
. 노트; 이 서비스는 날짜를 정수 (예 : 20130515)로 안정적으로 렌더링하므로 온 전성 검사에 가깝습니다.
ContainsKey
이 예외를 던져서는 안되므로 내 TryParse에서 ForecastData["forecast_date"]
을 참조해야한다고 생각합니다.
내 질문은 이것입니다. ContainsKey가 false를 반환하면 TryParse가 실행되지 않아야합니다. 그렇다면 왜 한 문장에서 키의 존재를보고하고 다음 문장에서 그 존재를 부인할 것입니다 ... 우리가 자물쇠 안에 있고 우리가 작업하고있는 사전은 비 정적이고 지역적입니다.
제쳐두고; 이것은 일반적으로 국장이 다음 장거리 예측을 발표 할 때 오후에 발생합니다. 예외는 몇 페이지의로드에 대해 발생하고 권한 자체에 대해 발생합니다. 여기
는 코드가 실패하지만 당신이 무엇을보고
Trace
을 활용 고려해야하는 이유
private Dictionary<string, string> Get7DayForecast()
{
int linenumber = 0;
int locationNameKey = 0;
List<string> keys = new List<string>();
Dictionary<string, string> myLocationData = new Dictionary<string, string>();
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(ForecastURL);
ftp.Method = WebRequestMethods.Ftp.DownloadFile;
ftp.Credentials = new NetworkCredential();
FtpWebResponse ftp_response = (FtpWebResponse)ftp.GetResponse();
if (ftp_response.WelcomeMessage.StartsWith("230") && ftp_response.StatusDescription.StartsWith("150"))
{
Stream ftp_responseStream = ftp_response.GetResponseStream();
StreamReader ftp_reader = new StreamReader(ftp_responseStream);
while (ftp_reader.Peek() >= 0)
{
linenumber++;
string line = ftp_reader.ReadLine();
List<string> temp = (List<string>)line.Split(ForecastDelimiter).ToList<string>();
if (linenumber == 1)
{
//Break if the header line does not contain the fields we require
if (!ForecastRequiredFields.All(line.Contains)) { break; }
keys = temp;
locationNameKey = keys.IndexOf(ForecastLocationFieldName);
}
else if (temp.Count == keys.Count && temp[locationNameKey] == ForecastLocationName)
{
for (int i = 0; i < keys.Count; i++)
{
myLocationData.Add(keys[i], temp[i]);
}
//Break if we've just parsed the data we were looking for
break;
}
}
ftp_reader.Close();
}
ftp_response.Close();
return myLocationData;
}
사전이 잠금 장치 내에서 정의되는 것이 중요합니까? 자물쇠 안에 정의 된 것은 쓰레드에 안전하다는 것을 알았습니다. –
'lock' 문에 의해 다중 스레드를 사용하고 있다고 가정합니다. 'Get7DayForecast'가 반환 한 동일한 객체에서 itens를 제외하는 다른 메소드는 없습니까? – fhelwanger
흠 ... 아니'Get7DayForecast'는'lock' 문 안에서'UpdateWeather'에 의해서만 사용됩니다. 또한 크게 캡슐화되어 있습니다. 서비스의 FTP 주소 (예 ... FTP)와 데이터를 가져 오려는 City의 코드를 제외하고 모든 객체는 메소드에 정의되어 있습니다. –