2

まず、私は LINQ とラムダ式にこの不可解な愛情を持っています :)
そこで、LINQ を使用して、特定の名前パターンに従ってディレクトリからファイルを取得し、それらを順序付け、合計の長さまで蓄積することになっている非常に簡単なコードを作成しました。蓄積されたファイルの数が特定のしきい値を超えています:

IEnumerable<FileInfo> l_allFiles = new DirectoryInfo(l_sDirName).GetFiles().Where(l_fileInfo => ms_pattern.IsMatch(l_fileInfo.Name)).OrderBy(l_fileInfo => l_fileInfo.CreationTime);
int l_nFilesTotal = l_allFiles.Count();
if (nFilesTotal > 0)
{
    long l_nAccumulatedCmdLength = 0;
    IEnumerable<FileInfo> l_selectedFiles = l_allFiles.TakeWhile(l_fileInfo => (l_nAccumulatedCmdLength += l_fileInfo.Length) <= Settings.Default.Threshold);

    int l_nNumOfSelected = l_selectedFiles.Count();
    if (l_nNumOfSelected > 0)
    {
        l_ret = new A { Files = l_selectedFiles };
    }
}


さて、このコードは、見つかったすべてのファイルが一緒になってしきい値を超えない場合に正常に機能します。
見つかったすべてのファイルが に選択されるとすぐにl_selectedFiles、ほとんどの場合、空でなくても0l_selectedFiles.Count()が返されます。まれに、正しい値を返すときに、Aクラスでを連続して呼び出すと0が返されます。 さらに厄介なことに、デバッガーはメソッドの実行後ではなく、次のステートメントの実行後に常に の値を更新します。すべてのファイルが選択されていない場合、 の値が常に期待どおりになるとは限りません... 全体像を完成させるために、 Microsoft Visual Studio 2010 Ultimatel_selectedFilesl_selectedFiles.Count()Files.Count()
l_nAccumulatedLengthTakeWhile()l_selectedFiles.Count()l_nAccumulatedLength
Windows 7 Professionalと私のプロジェクトは.NET4.0を対象としています。

誰でもこの動作や修正方法について説明やヒントを与えることができますか? 私はかなり迷っており、この問題をどのように正確にデバッグして解決するか想像することさえできず、コミュニティが私の最後の希望だからです。

皆様、早々にお返事、コメントありがとうございます。

4

1 に答える 1

3

クエリ内の変数を変更しています:

long l_nAccumulatedCmdLength = 0;
IEnumerable<FileInfo> l_selectedFiles = l_allFiles
     .TakeWhile(l_fileInfo => (l_nAccumulatedCmdLength += l_fileInfo.Length) <=
                                   Settings.Default.Threshold);

l_nAccumulatedCmdLengthあなたの状態の変化に注意してくださいTakeWhile

これは非常に悪い考えであり、評価するたびにシーケンスが異なる結果をもたらすことになります。やらないでください。それが問題の原因であると強く疑っています。

この部分に注意してください。

さらに、デバッガーは常に l_nAccumulatedLength の値を、TakeWhile() メソッドの実行後ではなく、次の l_selectedFiles.Count() ステートメントの実行後に更新します。

…とても分かりやすく説明されています。TakeWhileシーケンスを反復処理しません。遅延評価される新しいシーケンスを構築するだけです。

一貫した結果を得たい場合はToList... を使用しますが、そもそもクエリ内の変数を変更しない方がはるかに良いでしょう。必要に応じて、値が「これまでのサイズ」でAggregateある一連のTuple<FileInfo, long>値を作成するために使用します。long

于 2012-08-17T21:57:56.390 に答える