c#不会无缘无故地中断循环

本文关键字:中断 循环 无缘无故 | 更新日期: 2023-09-27 17:48:56

我正在写一些代码来解析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;
            }
        }
    }
}

vhorules对象

class vhostRules { public string key; public string value; }

vhostRules基本上是一个保存键和值的类

现在的问题是上面读文件的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 "

c#不会无缘无故地中断循环

提供一个实际的答案:

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

我能看到的最有可能出现异常的行是:

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[0]和param[1]是什么。我有一种感觉,他们是好的,它实际上是某处的addRule方法,异常被抛出…

因此,再次在addRule方法中的代码周围添加错误处理,并查看输出的内容。查看堆栈跟踪,检查行号,并向我们准确显示其中发生了什么。

不是解决您的问题的办法,但至少做了一些清理:更改这一行:

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

我想我找到了。对每个虚拟主机定义中的每一行执行以下代码:

/* 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个空格分隔的值。对于所有都是如此,除了对于最后一个:</VirtualHost>

我希望你得到一个ArrayIndexOutOfBoundsException(或任何在。net中被称为),但似乎有些东西吞下了它。