4

別の質問では、はい、文書化されていない の値でCreateDirectory失敗することがあり、状況を処理する正しい方法はおそらく数回再試行することであることがわかりました。このようなアルゴリズムを実装するのは簡単ですが、再現方法がわからない場合にテストするのはそれほど簡単ではありません。GetLastErrorERROR_ACCESS_DENIED

なぜこれが起こるのかについての理論は必要ありません。Windowsのバグかもしれませんね。また、設計による場合もあります。最終的には、Microsoft が動作を出荷したため、この時点では問題ではなく、対処する必要があります。

また、マルチタスク オペレーティング システムの理論と、Windows での一般的な実装方法についても説明する必要はありません。システムソフトウェアを書いて生計を立てています。私は他にほとんど理解していません。

私が今必要としているのは、失敗を再現するための信頼できる方法です。これにより、対処するコードのテスト ケースを作成できます。これが私がこれまでに試したことです:

  • 私はテスト プログラム P1 を作成しました。このプログラムは、親となるオブジェクトの内容をゆっくりと繰り返し列挙します。同様に、親になる予定のディレクトリの削除と作成を繰り返し試行するだけのテスト プログラム P2 を作成しました。列挙を長時間開いたままにしておくと、問題が発生する可能性が高くなる可能性があると考えました。P2 を単独で実行すると、時折障害が発生します (約 10 ミリ秒の間、数分おきに発生します)。P1 と P2 を同時に実行しても、障害が頻繁に発生したり、長くなったりすることはないようです。

  • P2 の 2 つのインスタンスを同時に実行しましたが、障害が頻繁に発生したり長くなったりすることはないようです。

  • ディレクトリに加えてファイルを作成できるように P2 を変更しました。これを P1 と同時に実行しても、障害が頻繁に発生したり、長くなったりすることはないようです。

  • P1 と P2 の複数のインスタンスをすべて同時に異なるパラメーターで実行しましたが、それによって失敗が頻繁になったり長くなったりすることはないようです。

  • 私は、アイテムを親となるものに出し入れするテスト プログラム P3 を作成し、P2 と同時に P3 を実行しました。

他のアイデアはありますか?

4

2 に答える 2

1

質問を理解していることを再確認することから始めましょう。以下のスニペットのようなものを実行すると、最終的に失敗することが予想されますよね?

while (true)
{
    System.IO.Directory.CreateDirectory( ".\\FooDir" );
    System.IO.Directory.Delete( ".\\FooDir" );
}

アプリケーションがそのファイルへのハンドルを開いているシステムで実行されている唯一のものである場合、これはバグのように感じます。したがって、OSのバージョンを知っていると役立ちます。

一方、システム内にハンドルを少しの間開いたままにしているものがある場合、これがバグであるかどうかはもう少しあいまいになります。やみくもにファイルやディレクトリを取得しようとするものの数は、あなたを驚かせるかもしれません。たとえば、ナイーブなインデクサーは、そのディレクトリにアクセスして列挙したり、インデックスを作成するファイルを探したりする場合があります。彼と衝突した場合は、blammoです。同様にナイーブなアンチウイルスフィルター、または他のファイルシステムフィルターもそれを突っ込んでいる可能性があります(この場合、それはまだバグのように感じます)。

これらの方法のようなサービスを提供して、邪魔にならないようにするために、OSで行ったことはほとんどありません。インデクサーをオフにした場合、アンチウイルス、アンチマルウェアをオフにした場合、それは再現されますか?そこから進むことができ、うまくいけば、新しいビットですでに修正されていることがわかります(そのステートメントには多くの仮定が含まれていました)。

もう1つの比較的興味深い雑学は、ERROR_ACCESS_DENIEDがシステム内の複数の基になるステータスからマップされるWin32エラーであるということです(たとえば、この記事を参照してください)。したがって、もう少し深く掘り下げることができれば、ファイルシステムがアプリに何を伝えようとしているのかを知ることができるかもしれません(アクセスが拒否された以上の場合)。

私たちは、あなたが実際にあなたのアプリがあなたのファイルとディレクトリを突っついている唯一のものであると仮定することができるかどうかについての会話に入るかもしれません。あなたはおそらくそれがどこに行くかを推測することができます。

于 2010-08-27T15:51:55.447 に答える
1

あなたの列挙/削除/作成がハンドルとの同期の問題を引き起こしていると推測します。CreateDirectory が CreateFile のようなものである場合 (その背後にあるロジックは共有されると思います)、CreateFile と同様の動作が見られます。

以前に DeleteFile を呼び出した結果、削除が保留されているファイルに対して CreateFile を呼び出すと、関数は失敗します。オペレーティング システムは、ファイルへのすべてのハンドルが閉じられるまで、ファイルの削除を遅らせます。GetLastError は ERROR_ACCESS_DENIED を返します。

于 2010-09-01T21:34:39.680 に答える