如何检查递归方法是否已经结束?

时间:2011-02-08 17:58:45

标签: c# .net recursion

我刚刚完成了这个递归方法:

/// <summary>
/// Recursively process a given directory and add its file to Library.xml
/// </summary>
/// <param name="sourceDir">Source directory</param>
public void ProcessDir(string sourceDir)
{
    string[] fileEntries = Directory.GetFiles(sourceDir, "*.mp3");
    foreach (string fileName in fileEntries)
    {
        Song newSong = new Song();
        newSong.ArtistName = "test artist";
        newSong.AlbumName = "test album";
        newSong.Name = "test song title";
        newSong.Length = 1234;
        newSong.FileName = fileName;

        songsCollection.Songs.Add(newSong);
    }

    string[] subdirEntries = Directory.GetDirectories(sourceDir);
    foreach (string subdir in subdirEntries)
    {
        if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
        {
            ProcessDir(subdir);
        }
    }
}

一切都按预期工作,我遇到的唯一问题是:我如何知道此方法何时完成执行?在.NET中是否有为此目的而做的事情?

6 个答案:

答案 0 :(得分:7)

.NET没有什么特别的东西告诉你这个......基本上,第一次调用ProcessDir会在递归结束后返回。

答案 1 :(得分:2)

嗯,您可以在初始ProcessDir调用之后总是输入一行代码表示执行结束:

ProcessDir("MyDir");
Console.WriteLine("Done!");

答案 2 :(得分:1)

您可以尝试使用全局变量来跟踪它。

private int _processDirTrack = 0;

public void ProcessDir(string sourceDir)
{
    _processDirTrack++;  // Increment at the start of each

    string[] fileEntries = Directory.GetFiles(sourceDir, "*.mp3");
    foreach (string fileName in fileEntries)
    {
        Song newSong = new Song();
        newSong.ArtistName = "test artist";
        newSong.AlbumName = "test album";
        newSong.Name = "test song title";
        newSong.Length = 1234;
        newSong.FileName = fileName;

        songsCollection.Songs.Add(newSong);
    }

    string[] subdirEntries = Directory.GetDirectories(sourceDir);
    foreach (string subdir in subdirEntries)
    {
        if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
        {
            ProcessDir(subdir);
        }
    }

    _processDirTrack--;  // Decrement after the recursion. Fall through means it got to
                         // the end of a branch

    if(_processDirTrack == 0)
    {
        Console.WriteLine("I've finished with all of them.");
    }
}

答案 3 :(得分:1)

我假设RQDQ提供的(尽管是正确的)答案不是您要找的那个?

如果你有一个长期运行的任务,你要检查它的走向,你可以使用BackgroundWorker

当然,这个后台工作者并没有神奇地知道要处理多少文件,因此每当你能估计出你的距离时,你就必须调用ReportProgress。

为了尝试估算处理需要多长时间,您可以尝试以下方法:

  • 检查文件夹占用的磁盘空间总量,并跟踪已经处理的内容。
  • 检查您必须处理的文件数量与仍需要处理的文件数量。

答案 4 :(得分:1)

如果您想知道它何时结束以在您的应用程序中发出信号/启动另一个进程,您可以举起一个事件。这可能是过度杀戮,但嘿,如果它适合你的需要,它是另一种看待它的方式。您只需要将事件添加到ProcessDir()所属的类中。

private int _processDirTrack = 0;
public event EventHandler DirProcessingCompleted;

在你的方法结束时,你会举起你的活动

DirProcessingCompleted(this, new EventArgs());

您使用代码中其他位置的事件处理程序订阅这些事件

myClass.DirProcessingCompleted += new EventHandler(ProcessingComplete_Handler);

注意:您不必以这种方式订阅活动;您也可以使用委托或lambda表达式订阅。

要将它全部包装起来,您可以创建在对象引发事件时调用的方法。

private void ProcessingComplete_Handler(object sender, EventArgs e)
{
    // perform other operations here that are desirable when the event is raised ...
}

答案 5 :(得分:0)

我猜你要弄清楚的是如何知道你已经达到了将要发生的最深层次的递归。

在这种情况下,当subdirEntries为空时,您将知道您正处于函数的最后一次递归调用,因为该函数将不再递归。这是你能做的最好的,关于如何知道一个函数何时停止递归,没有通用的答案。这完全取决于递归条件是什么。

编辑:想澄清一下。这将在每次结束单个递归链时进行检查。考虑到您的代码每次调用可以多次递归,我的解决方案只表示单个递归链的结束。在递归导航树的情况下,这将在每个叶节点处发生,而不是在最深的递归级别。