(私は似たようなスレッドを検索しましたが、このような問題に対処するものは見つかりませんでした。ここにそしてここに。)
私たちのアプリのパフォーマンスを評価していて、いくつかのIOException「リソースが見つかりません」を受け取っていることに気付いています。何回起こっているのか(私はユーザーのアプリの使い方に大きく依存しますが)正確にはわかりませんが、少なくとも1ダースかそこらです。
私は、一般的な例外は、ファイルI / O呼び出しがそうであるようにパフォーマンスが高いと思います。File.Exists()
。試してロードする前にファイルが存在するかどうかをチェックすることは常に良い習慣であることを私は知っています。私の質問は、この特定のファイルが存在するかどうかを確認した場合、どの程度のパフォーマンスの向上が見られるかということです。 (繰り返しますが、「とにかくこれを実行する必要があります」は無視します。パフォーマンスについて理解しようとしているだけです)。
オプション1:
try
{
return (ResourceDictionary) Application.LoadComponent(uri);
}
catch (Exception)
{
//If it's not there, don't do anything
}
これは余分なIO呼び出しをしませんが、時々投げられて飲み込まれる例外を投げます。
オプション2:
if(File.Exists(uri))
{
return (ResourceDictionary) Application.LoadComponent(uri);
}
一般に、ファイルがすべき存在する場合(つまり、それはあなたのアプリケーションのデプロイメントの一部です)、それから私は例外チェックを使用しますが、それ以外は何もしません。これは、この場合、例外が本当に例外的で予想外の状況であるためです。
ファイルがユーザーによって入力されたものである場合、存在を確認することは潜在的に意味があります。ただし、ファイルとしては、これでも例外処理が不要になるわけではありません。できたチェックしてから開いたり使用したりするまでの間に削除してください。そのように、あなたはまだ例外処理を必要としている - その場合あなたはよろしくまだ最初のオプションコードだけを使いたいのですが、たとえファイルが存在しなくても例外処理が常に振る舞いを提供するのに十分きれいであることを確認してください。
私はあなたの2つのオプションの間に大きなパフォーマンスの違いがあるのを見ることができません。ほとんどの作業はファイルの場所を特定して読み取ることなので、どちらの場合もそうする必要があります。アプリケーションの実行中にユーザーがこのファイルを追加または削除することを想定していない場合は、便利なことがあります。だからあなたは何かをするかもしれません
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は内部的にも例外をスローします。そのため、パフォーマンスは非常によく似ています。
これは、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;
}