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

发布于 2024-10-16 11:22:39 字数 1019 浏览 0 评论 0原文

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

/// <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 中有专门为此目的而制作的东西吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

半衬遮猫 2024-10-23 11:22:39

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

There's nothing special in .NET that tells you this... Basically, the first call to ProcessDir will return after the recursion has ended.

爱*していゐ 2024-10-23 11:22:39

好吧,您总是可以在初始 ProcessDir 调用之后放置一行代码来指示执行结束:

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

Well, you could always put a line of code indicating the end of execution after your initial ProcessDir call:

ProcessDir("MyDir");
Console.WriteLine("Done!");
绳情 2024-10-23 11:22:39

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

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

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.");
    }
}
葬花如无物 2024-10-23 11:22:39

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

如果您有一个长时间运行的任务,并且想要检查其进度,可以使用 BackgroundWorker.

当然,这个后台工作人员不会神奇地知道还要处理多少文件,因此只要您可以估计进度,就必须调用 ReportProgress。

为了尝试估计处理需要多长时间,您可以尝试以下操作:

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

I'm assuming the (albeit correct) answer RQDQ provided isn't the one you are looking for?

In case you have a long running task of which you want to check how far it is along you can use a 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.

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.
撕心裂肺的伤痛 2024-10-23 11:22:39

如果您想知道应用程序中何时结束发出信号/启动另一个进程,您可以引发一个事件。这可能有点过头了,但是嘿,如果它适合您的需要,这是另一种看待它的方式。您只需向 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 ...
}

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.

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.

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 ...
}
扎心 2024-10-23 11:22:39

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

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

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

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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文