简体   繁体   English

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

[英]How to check if a recursive method has ended?

I've just finished making this recursive method: 我刚刚完成了这种递归方法:

/// <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);
        }
    }
}

Everything is working as expected, the only problem I'm having is: How do I know when this method finishes execution? 一切都按预期工作,我唯一的问题是:我怎么知道该方法何时完成执行? Is there something made for that very purpose in .NET? .NET是否有专门为此目的制作的东西?

.NET中没有什么特别的可以告诉您的...基本上,在递归结束之后,对ProcessDir的第一次调用将返回。

Well, you could always put a line of code indicating the end of execution after your initial ProcessDir call: 好吧,您总是可以在最初的ProcessDir调用之后放一行代码,以指示执行结束:

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

You could try using a global variable to keep track of it. 您可以尝试使用全局变量来跟踪它。

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.");
    }
}

I'm assuming the (albeit correct) answer RQDQ provided isn't the one you are looking for? 我假设提供的(尽管是正确的)RQDQ答案不是您要的吗?

In case you have a long running task of which you want to check how far it is along you can use a BackgroundWorker . 如果您有一项长期运行的任务,想要检查任务的执行距离,可以使用BackgroundWorker

Ofcourse this background worker doesn't magically know how much more files to process, so you have to call ReportProgress whenever you can give an estimate of how far along you are. 当然,这个后台工作人员并不神奇地知道要处理多少文件,因此,只要您可以估算出要处理的文件数,就必须调用ReportProgress。

In order to try to estimate how much longer the processing will take, you could try the following: 为了尝试估计处理将花费多长时间,您可以尝试以下操作:

  • Check for total disk space the folder occupies, and keep track of much you already processed. 检查文件夹占用的磁盘总空间,并跟踪已处理的磁盘空间。
  • Check for amount of files you have to process vs. how much you still have to process. 检查您必须处理的文件数量以及仍然需要处理的文件数量。

If you're wanting to know when it ends to signal/start another process in your application, you could raise an event. 如果您想知道何时结束以信号通知/启动应用程序中的另一个进程,则可以引发一个事件。 This may be over kill, but hey, it's another way to look at it if it suits your need. 这可能是致命的,但是,嘿,这是满足您需要的另一种查看方法。 You just need to add an event to the class where ProcessDir() is a member. 您只需要向ProcessDir()是成员的类中添加一个事件。

private int _processDirTrack = 0;
public event EventHandler DirProcessingCompleted;

At the end of your method you would raise your event like so 在方法结束时,您将像这样引发事件

DirProcessingCompleted(this, new EventArgs());

You subscribe to these events with an eventhandler somewhere else in your code 您在代码中的其他位置使用事件处理程序订阅了这些事件

myClass.DirProcessingCompleted += new EventHandler(ProcessingComplete_Handler);

Note: you don't have to subscribe to an event in this manner; 注意:您不必以这种方式订阅活动; you could also subscribe with a delegate or lambda expression instead. 您还可以订阅委托或lambda表达式。

To wrap it all up you create your method that is called whenever an event is raised by the object. 要将其全部包装起来,您可以创建您的方法,该方法在对象引发事件时被调用。

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

I'm guessing what you're trying to figure out is how to know that you've reached the deepest level of recursion that is going to occur. 我想您要弄清楚的是如何知道您已经达到了将要发生的最深层次的递归。

In this case, you'll know that you're in the last recursive call of the function when subdirEntries is empty, since the function will no longer recurse at that point. 在这种情况下,您会知道当subdirEntries为空时,您正在该函数的最后一个递归调用中,因为该函数将不再在该位置递归。 That's the best you can do, there's no universal answer as to how to know when a function will cease to recurse. 那是您所能做的最好的事情,关于如何知道某个函数何时将停止递归,没有统一的答案。 It's entirely dependent upon what the conditions to recurse are. 这完全取决于要递归的条件。

Edit: Wanted to clarify. 编辑:想要澄清。 This will check each time you end a single chain of recursions. 每次结束单条递归链时,都会进行检查。 Considering your code can recurse multiple times per call, my solution will only signify the end of a single chain of recursions. 考虑到您的代码可以在每次调用中重复多次,因此我的解决方案仅表示单条递归链的结束。 In the case of recursively navigating a tree, this will occur at every leaf node, not at the deepest level of recursion. 在递归地导航树的情况下,这将发生在每个叶节点上,而不是在最深层次的递归上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM