C#没有无缘无故地打破循环[关闭]

Posted

技术标签:

【中文标题】C#没有无缘无故地打破循环[关闭]【英文标题】:C# not breaking loop for no reason [closed] 【发布时间】:2011-07-29 23:33:28 【问题描述】:

我正在编写一些解析 Apache 配置文件的代码。

正在解析的文件:

NameVirtualHost *:80

#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
    ServerName dummy-host.example.com
    ServerAlias www.dummy-host.example.com
    ErrorLog "logs/dummy-host.example.com-error.log"
    CustomLog "logs/dummy-host.example.com-access.log" common
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host2.example.com
    DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
    ServerName dummy-host2.example.com
    ErrorLog "logs/dummy-host2.example.com-error.log"
    CustomLog "logs/dummy-host2.example.com-access.log" common
</VirtualHost>

这是解析器方法filePath是上面文件的路径。

public void readFile(string filePath)
    
        /* read the file path provided */
        StreamReader reader = new StreamReader(filePath);
        string content = reader.ReadToEnd();

        /* remove the comments from the file */
        string[] lines = content.Split('\n');
        string newContent = "";
        foreach(string line in lines)
            char[] chars = line.ToCharArray();
            if(chars[0] != '#')
                newContent += line+"\n";
            
        

        /* search for Virtual hosts and save them */
        string regEx = "<VirtualHost [^>]*>[^<]*</VirtualHost>";
        MatchCollection coll = Regex.Matches(newContent, regEx, RegexOptions.IgnoreCase);
        string[] vhosts = new string[coll.Count];
        int counter = 0;

        /* go though them and save them into a string array */
        foreach (Match match in coll)
        
            vhosts[counter] = (match.Value);
            counter++;
        

        /* set the number of vhosts */
        hosts = new vhost[vhosts.Count()];

        /* go though the string array */
        for (int c = 0; c < vhosts.Count(); c++ )
        

            MessageBox.Show("hi");

            /* set the host string to current vhost string */
            string host = vhosts[c];
            /* get the lines from the vhost */
            string[] lines2 = host.Split('\n');
            /* create the new save object in the array of vhosts */
            hosts[c] = new vhost();
            /* tell the console what were proccessing */
            Console.WriteLine((c+1).ToString() + " of " + vhosts.Count().ToString());
            /* for each line add the rule to the correct vHost via the counter for looping though the vhosts */
            for (int i = 0; i < lines2.Count(); i++)
            
                /* set the string line to the line were currently on */
                string line = lines2[i];
                /* get rid of whitespace and split on the space (' ')*/
                string[] param = line.Trim().Split(' ');
                /* provde the current vHost number and the key and value in the config file */
                hosts[c].addRule(param[0], param[1]);
            
        
    

hostsvHost[] vHost 如下

class vhost

    public vhostRules[] rules = new vhostRules[1];

    public string getRuleValue(string key)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            if (key == Rule.key)
                return Rule.value;
        
        return "";
    

    public vhostRules getRule(string key)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            if (key == Rule.key)
                return Rule;
        
        return new vhostRules();
    

    public vhostRules[] getRules()
    
        return rules;
    

    public void addRule(string key, string rule)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        int counter = 0;
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            rules[i] = Rule;
            counter++;
        
        rules[counter] = new vhostRules();
        rules[counter].key = key;
        rules[counter].value = rule;
    

    public void removeRule(string key)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            if (key != Rule.key)
                rules[i] = Rule;
        
    

    public void changeRule(string key, string value)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            if (key != Rule.key)
            
                rules[i] = Rule;
                rules[i].value = value;
            
        
    

vhostRules 对象

class vhostRules public string key; public string value;

vhostRules基本上就是一个保存key和value的类

现在问题是上面读取文件的hosts[c].addRule(param[0], param[1]);,您可以看到它在vhost 类中再次调用addRule,即使我清空addRule,所以里面没有代码仍然不起作用。

这是我可以显示问题的唯一方法,没有更小的方法可以复制,因为错误似乎与编译的最终结果有关

我发现的唯一方法是注释或从我的代码中删除hosts[c].addRule(param[0], param[1]); 然后它可以工作,但是当我清空它时,它不起作用,理论上是不正确的

单步执行代码并没有发生错误,它只运行一次循环,

没有错误发生,包括没有无声的死亡,没有例外,没有冻结/崩溃

更新 更新阅读器

try

    hosts[c].addRule(param[0], param[1]);
catch (Exception e)  Console.WriteLine(e.Message); 

提供输出

1 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
2 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array

断点信息

param = string[2] 
    [0] = "ServerAdmin" 
    [1] = "webmaste

r@dummy-host.example.com"

【问题讨论】:

“除了不运行代码没有问题”。男孩,我认为这是大多数无法运行的代码的问题! 这是一个公平的评论:“我的车没有任何问题,只是引擎无法启动”。 另外,我强烈建议您发布代码的相关部分...我不会等待 45 秒才能从 MegaUpload 下载某些内容,以便能够开始帮助您没有问题的代码。 所以向我们展示relevant 部分,它不可能是整个事情都不起作用。尝试在尽可能小的示例中重现它并发布它。 @Barkermn01:如果你的应用程序那么大,那么没有人会仔细查看它。尝试生成一个 SSCCE 来证明您的问题。在这样做的过程中,您不妨找出问题所在。 【参考方案1】:

不是解决您的问题,但至少是一些清理:更改此行:

public vhostRules[] rules = new vhostRules[1];

进入

private List<vhostRules> rules = new List<vhostRules>();

那么您不需要每次需要添加项目时都重新复制该数组,只需 .Add() 即可。

你可能会改变

public vhostRules[] getRules()

    return rules;

进入

using System.Linq;
public vhostRules[] getRules()

    return rules.ToArray();

【讨论】:

我要为此 +1,只是因为我一直很想在查看代码时说很多类似的话。 @Barkermn01 - 请注意,尽可能多地重构此代码,您和我的调试时间会大大轻松。 你会喜欢这个的,但这为我修复了最后一个错误,所以谢谢【参考方案2】:

只是为了提供一个实际的答案:

我最初的猜测 - 这只是一个猜测,因为我们没有我们需要的所有信息 - 是循环中某处抛出了异常。

我能看到的最有可能的例外是以下行:

hosts[c].addRule(param[0], param[1]);

vhost 类中的 addRule 方法做了一些非常时髦的事情,但同样,我们没有所有信息,所以我不能肯定。

我们需要什么

我们至少需要知道发生了什么。是否抛出异常?它到达哪条线?它会默默地死去吗?您是否已单步执行代码?

请帮助我们帮助您...

更新 所以,问题出在:

string[] param = line.Trim().Split(' ');                
hosts[c].addRule(param[0], param[1]);            

或者:

public void addRule(string key, string rule)
    
        vhostRules[] currentRules = rules;
        rules = new vhostRules[currentRules.Count()];
        int counter = 0;
        for (int i = 0; i < currentRules.Count(); i++)
        
            vhostRules Rule = currentRules[i];
            rules[i] = Rule;
            counter++;
        
        rules[counter] = new vhostRules();
        rules[counter].key = key;
        rules[counter].value = rule;
    

或者:

vhostRules的构造函数内,如行所示:

rules[counter] = new vhostRules();

现在,您为rules[] 中的键值对使用的键是什么?

你可以试试 换行:

string[] param = line.Trim().Split(' ');

到:

string[] param = line.Trim().Split(new char[] ' ', 2);

这将允许您在某些行的末尾保留common...这可能不会导致您的主要问题,但它可能至少是一个问题。

更新 2 在上面的那行(string[] param = line.Trim().Split(new char[] ' ', 2);之后设置断点,看看param实际设置成什么。加个watch,看看究竟param[0]和param[1]是什么。我有一种感觉他们没问题,实际上是在 addRule 方法的某个地方引发了异常......

同样,在 addRule 方法中围绕代码添加错误处理,并查看输出的内容。查看堆栈跟踪,检查行号,并准确地向我们展示其中发生了什么。

【讨论】:

任何未处理的异常都会被抛出到调试器中,你可以看到没有错误处理,所以所有的都是未处理的 首先,您还没有回答我们需要什么部分中的任何内容。其次,不一定:检查VS中的Debug菜单,选项和设置。确保启用“启用异常助手”和所有其他相关选项。 伙伴去读我说“我通过代码解决了问题”我告诉你它没有错误并告诉你没有抛出异常是的我的 VS 设置正确以处理异常所以这个当我确认我为什么要下载代码时,你对我的看法是这样的,这样你就可以看到这个 当然,这就是您所说的,我对此没有异议。因此,从外观上看,您在 addRule 方法中存在问题。这导致我们需要查看vhostRules 的构造函数,由new vhostRules(); 调用。您提到从 addRule 方法中删除所有代码会留下相同的结果,这让我相信规则没有正确添加到集合中。你用什么作为收藏的钥匙?这是在某个地方复制的吗? class vhostRules public string key; public string value; 只是没有构造或任何东西【参考方案3】:

我想我找到了。您为每个虚拟主机定义中的每一行执行此代码:

/* get rid of whitespace and split on the space (' ')*/
string[] param = line.Trim().Split(' ');
/* provde the current vHost number and the key and value in the config file */
hosts[c].addRule(param[0], param[1]);

这假定每行至少包含 2 个空格分隔的值。这对所有人都是如此除了最后一个:&lt;/VirtualHost&gt;

我希望你得到一个 ArrayIndexOutOfBoundsException(或任何在 .NET 中调用的东西),但似乎有些东西会吞下它。

【讨论】:

刚看到同样的事情 :) 我刚刚让他将整个事情包装在一个 try/catch 块中,看看我们是否可以获得一些异常输出。除非它被进一步吞噬,否则我们实际上应该做点什么。 干得好,伙计们,我得到“索引超出了数组的范围”,但是为什么在没有处理到位的情况下处理这是一个燃烧的奇迹

以上是关于C#没有无缘无故地打破循环[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Qt 应用程序无故崩溃? [关闭]

打破节点repl中的无限循环?

1个元素JS,CSS的多个动画[关闭]

elasticsearch无故关闭,Log无报错

简单的for循环不起作用[关闭]

CAD无缘无故总是自动关闭,是否兼容问题?