如何检查递归函数是否已完成?

时间:2016-08-19 13:51:00

标签: c# recursion ftp

我正在为我的游戏制作修补程序。修补程序使用用户计算机上的本地文件检查ftp服务器上每个文件的大小,如果不同,则从ftp服务器下载新文件。

我想添加一条打印消息“更新完成!X文件已更新”。当它检查了所有文件但是我知道函数什么时候到处都结束了吗?

private void CheckForUpdates(string ftpPath, string localPath)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath);
    request.Credentials = new NetworkCredential(ftpUser, ftpPass);
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);

    List<string> files = new List<string>();

    string line = reader.ReadLine();
    while (!string.IsNullOrEmpty(line))
    {
        if (line != "." && line != ".." && line != ".htaccess")
        {
            files.Add(line);
        }

        line = reader.ReadLine();
    }

    response.Close();
    responseStream.Close();
    reader.Close();

    foreach (string file in files)
    {
        string newFtpPath = ftpPath + "/" + file;
        string newLocalPath = localPath + "/" + file;

        new Thread(() => AppendText("Checking " + newLocalPath + Environment.NewLine)).Start();

        if (IsFile(newFtpPath))
        {
            if (File.Exists(newLocalPath))
            {
                if (!IsFileEqual(newFtpPath, newLocalPath))
                {
                    new Thread(() => AppendText(file + " is out of date or corrupted. Patching in progress..." + Environment.NewLine)).Start();
                    new Thread(() => Download(newFtpPath, newLocalPath)).Start();
                }  
            }
            else
            {
                new Thread(() => AppendText(file + " is missing. Patching in progress..." + Environment.NewLine)).Start();
                new Thread(() => Download(newFtpPath, newLocalPath)).Start();
            }
        }
        else
        {
            if (!Directory.Exists(newLocalPath))
            {
                new Thread(() => AppendText(file + " is missing. Patching in progress..." + Environment.NewLine)).Start();
                Directory.CreateDirectory(newLocalPath);
            }

            new Thread(() => CheckForUpdates(newFtpPath, newLocalPath)).Start();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这取决于;如果您所做的只是打印一种方法,那么在任何地方都可以知道它可能并不重要。

但是,如果您希望其他事情发生(或者您可能希望将来发生其他事情),您可以随时举办活动。这实际上是一种相当常见的模式,特别是如果它是一个异步操作(听起来它是有意义的,因为它是一个可能长期运行的任务)。

如果您正在使用任务并行,这实际上可以帮助您了解它何时完成(至少对于来电者而言)。

你的另一个问题是知道你创建的主题何时完成(因为即使你同步运行整个方法,它返回的事实并不能保证所有线程完成他们的工作)。当然,这取决于你的意思&#34;完成&#34; - 如果通过&#34;完成&#34;你的意思是&#34;该方法已将控制权交还给其来电者并且所有相关工作都已完成&#34;或者只是&#34;该方法已将控制权交还给其来电者。&#34; (换句话说,是否可以考虑方法&#34;完成&#34;如果它创建的某些线程仍在下载文件?如果您指望这些方法在方法返回时完成控制它的来电者这将是一个典型的竞争条件。)

如果您愿意,可以使用任务并行来帮助您了解线程是否已完成。另一种(一种愚蠢但有效的)方法是保持某种变量(以线程安全的方式更新)&#34;运行线程&#34; - 每次生成一个新线程时,都会以线程安全的方式递增计数,每当其中一个完成时,它会递减计数(再次以线程安全的方式)。 (如果您没有使用任务,出于性能原因,您也可以考虑使用线程池执行这些任务,而不是每次都创建新线程。)

答案 1 :(得分:1)

好的,我通过添加一个线程计数来解决问题。

  

我在这里看到的问题是你正在催生新线程。我会   绝对要跟踪你创建的线程数量   使用信号量之类的东西来控制

当我需要深入了解文件时添加线程数

threadCount++;
new Thread(() => CheckForUpdates(newFtpPath, newLocalPath)).Start();

在函数结束时检查是否只有1个线程

if(threadCount == 1)
    //print end message
else
    threadCount--;

感谢帮助人员!