(비슷한 스레드를 검색해 보았지만이 특정 문제를 해결 한 항목을 찾을 수 없었습니다.이리과이리.)
우리 앱의 성능을 평가 중이고 일부 IO 예외가 "리소스를 찾을 수 없습니다"라는 메시지가 나타납니다. 정확히 얼마나 많은 시간이 일어 났는지는 잘 모르겠지만 (대부분 사용자가 앱을 사용하는 방식에 달려있다.), 적어도 12 개 정도는된다.
나는 일반적으로 파일 I / O 호출처럼 성능이 비싸다고 가정합니다.File.Exists()
. 파일을로드하고로드하기 전에 파일이 있는지 항상 확인하는 것이 좋습니다. 내 질문은, 특정 파일이 존재하는지 확인하면 얼마나 많은 성능 향상을 볼 수 있습니까? (다시 말하지만, "어쨌든이 일을해야합니다."나는 단지 성능에 대한 이해를 얻으려고 노력하고 있음).
옵션 1:
try
{
return (ResourceDictionary) Application.LoadComponent(uri);
}
catch (Exception)
{
//If it's not there, don't do anything
}
이것은 여분의 IO 호출을하지 않지만 때로는 throw하고 삼키는 예외를 만듭니다.
옵션 2:
if(File.Exists(uri))
{
return (ResourceDictionary) Application.LoadComponent(uri);
}
일반적으로 파일할까요존재 (예 : 응용 프로그램 배포의 일부), 그렇다면 예외 검사 만 사용하면됩니다. 이 경우 예외는 실제로 예외적이고 예기치 않은 상황이기 때문입니다.
파일이 사용자가 입력 한 것 인 경우, 존재 여부를 확인하는 것이 잠재적 인 의미가 있습니다. 그러나이 경우에도 예외 처리가 필요하지 않습니다.할 수 있었다확인한 시간과 열어 본 시간 사이에 삭제 될 수 있습니다. 따라서 예외 처리가 여전히 필요합니다.이 경우 예외 처리가 필요합니다.할 수있다여전히 첫 번째 옵션 코드를 사용하고 싶지만 예외 처리가 파일이 존재하지 않더라도 항상 동작을 제공 할만큼 깨끗한 지 확인하십시오.
두 가지 옵션간에 큰 성능 차이가 있다는 것을 나는 볼 수 없습니다. 대부분의 작업은 파일 찾기 및 읽기 작업이므로 두 경우 모두 수행해야합니다. 사용자가 응용 프로그램이 실행되는 동안이 파일을 추가 / 제거 할 것을 예상하지 않으면 결과를 캐싱하는 것이 유용 할 수 있습니다. 그래서 당신은 뭔가를 할 수도 있습니다.
private static Dictionary<Uri, ResourceDictionary> _uriToResources =
new Dictionary<Uri, ResourceDictionary>();
public static ResourceDictionary GetResourceDictionary(Uri uri)
{
ResourceDictionary resources;
if (_uriToResources.TryGetValue(uri, out resources))
{
return resources;
}
try
{
resources = (ResourceDictionary)Application.LoadComponent(uri);
}
catch
{
// could prompt/alert the user here.
resources = null; // or an appropriate default.
}
_uriToResources[uri] = resources;
return resources;
}
이렇게하면 존재하지 않는 리소스를 반복적으로로드하지 못하게됩니다. 여기에 null 객체가 반환되지만 일부 기본값을 대체로 사용하는 것이 좋습니다.
File.Exists는 내부적으로 예외도 throw합니다. 따라서 성능은 매우 유사합니다.
다음은 File.Exists가 호출하는 도우미 메서드가 포함 된 File.cs의 코드입니다.
[SecurityCritical]
private static bool InternalExistsHelper(string path, bool checkHost)
{
try
{
if (path == null || path.Length == 0)
return false;
path = Path.GetFullPathInternal(path);
if (path.Length > 0 && Path.IsDirectorySeparator(path[path.Length - 1]))
return false;
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, path, false, false);
return File.InternalExists(path);
}
catch (ArgumentException ex)
{
}
catch (NotSupportedException ex)
{
}
catch (SecurityException ex)
{
}
catch (IOException ex)
{
}
catch (UnauthorizedAccessException ex)
{
}
return false;
}