5

(私は同様のスレッドを検索しましたが、この特定の問題に対処するものは見つかりませんでしたが、ここここなどの類似したスレッドがいくつかありました。)

アプリのパフォーマンスを評価していますが、「リソースが見つかりません」という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);
}
4

3 に答える 3

6

一般に、ファイル存在する必要がある場合(つまり、ファイルがアプリケーションのデプロイメントの一部である場合)、例外チェックのみを使用します。これは、この場合、例外が本当に例外的で予期しない状況であるためです。

ファイルがユーザーによって入力されたものである場合、存在を確認することは潜在的に意味のあるものになります。ただし、チェックしてから開いたり使用したりするまでの間にファイル削除される可能性があるため、これでも例外処理の必要性がなくなるわけではありません。そのため、例外処理が必要です。その場合でも、最初のオプションコードを使用することもできますが、ファイルが存在しない場合でも、例外処理が常に動作を提供できるように十分にクリーンであることを確認してください。 。

于 2012-08-20T20:26:23.027 に答える
1

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オブジェクトを返しますが、フォールバックとしてデフォルトを使用する方がよい場合があります。

于 2012-08-20T20:46:03.517 に答える
1

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;
    }
于 2017-12-04T02:35:27.383 に答える