代码没有同步抛出索引是超出范围的数组?

时间:2016-11-08 19:47:56

标签: c# arrays asp.net-mvc ado.net

在您将此问题标记为重复之前,这是我不理解的棘手部分。这个错误是零星的,我相信代码是正确的并且它始终有效,并且我在Reader部分内处理if else条件时可能出现的错误。这是代码:

public static Tuple<int, string> GetIDAndString(string term)
{
    try
    {
        using (SqlConnection con = GetConnection())
        using (cmd = new SqlCommand())
        using (myReader)
        {
            int ID = 0;
            string status = string.Empty;
            cmd.Connection = con;
            con.Open();
            cmd.CommandText = @"SELECT t.TableID, t.Status
                                FROM Table t WITH (NOLOCK) /* I know NOLOCK is not causing the mistake as far as I know */
                                WHERE t.Term = @term";
            cmd.Parameters.AddWithValue("@term", term);

            myReader = cmd.ExecuteReader();
            while(myReader.Read())
            {
                ID = myReader.IsDBNull(0) ? 0 : myReader.GetInt32(0);
                status = myReader.IsDBNull(1) ? string.Empty : myReader.GetString(1).Trim();
            }

            myReader.Close();

            return new Tuple<int, string>(ID, status);
        }
    }
    catch (Exception)
    {
        throw;
    }
}

我知道我应该使用一个类而不是一个元组,但我无法改变现有的代码,正如你所看到的那样。所以主要的问题是,在生产服务器中,该方法中有Index out of bounds array exception,但我无法确定问题所在。

即使在查询中找不到该术语,myReader也不会进入,我将返回ID = 0,status = string.Empty。有时当我调试代码并处理develpment server时,我的代码开始在所有地方崩溃,向我展示了测试代码的例外情况,我必须重新打开解决方案以避免这种情况(我没有&#t; t找到了解决方案,甚至没有清理解决方案。)

所以我希望有人在production server中有类似的经历。我没有生产服务器的规格,因此我对服务器一无所知。

4 个答案:

答案 0 :(得分:1)

首先,您不需要try/catch阻止,您不会对此做任何事情。在此之后不要在课堂上分享SqlDataReader,这可能会带来问题,而且问题可能来自于此。您一直在覆盖IDStatus的值。可能一个好主意是在您的查询上调用Top 1并使用正确的字段对其进行排序。此外,Dispose() SqlCommand SqlCommand的构造函数不需要SupressFinalization()TableID正在调用Status

为什么会出现此问题:想象一下,您的查询会返回包含SqlDataReaderstatic列的1000条记录,并且您正在进入while循环。在这一刻,其他一些用户进入你的应用程序并执行另一个方法,该方法覆盖public static Tuple<int, string> GetIDAndString(string term) { int ID = 0; string status = string.Empty; using (SqlConnection con = GetConnection()) { SqlCommand cmd = new SqlCommand(); cmd.Connection = con; con.Open(); cmd.CommandText = @"SELECT t.TableID, t.Status FROM Table t WITH (NOLOCK) /* I know NOLOCK is not causing the mistake as far as I know */ WHERE t.Term = @term"; cmd.Parameters.AddWithValue("@term", term); using(SqlDataReader myReader = cmd.ExecuteReader()) { while(myReader.Read()) { ID = myReader.IsDBNull(0) ? 0 : myReader.GetInt32(0); status = myReader.IsDBNull(1) ? string.Empty : myReader.GetString(1).Trim(); } } } return new Tuple<int, string>(ID, status); } 并返回仅有一列的5条记录。在循环的下一次迭代中,您将收到异常。因此,您永远不应将您的读者定义为整个班级的<div ng-repeat="item in contactos| orderBy:'displayName' | filter : consulta"> <ion-item class="item-stable" ng-click="abrirGrupo(item)" ng-class="{active: isGroupShown(item)}"> <i class="icon" ng-class="isGroupShown(item) ? 'ion-minus' : 'ion-plus'"></i> {{::item.displayName}} <label style="float:right" ng-show="muestra">elegido</label> </ion-item> <ion-item class="item-accordion" ng-repeat="i in item.phoneNumbers" ng-show="isGroupShown(item)"> <ion-checkbox ng-click="cambi()" ng-model="tel" class="checkbox-dark" ng-value=i.normalizedNumber> telefono: {{::i.normalizedNumber}} </ion-checkbox> </ion-item> </div> 。静态变量在所有应用程序用户之间共享。

$scope.cambi = function () {
            $scope.muestra = !$scope.muestra;
            console.log('elegido: ' + $scope.tel);
        };

$scope.contactos = [{
                "id": "1",
                "displayName": "Kate Bell",
                "phoneNumbers": [{
                    "number": "(555) 564-8583",
                    "normalizedNumber": "(555) 564-8583",
                    "type": "MOBILE"
                }, {
                    "number": "(415) 555-3695",
                    "normalizedNumber": "(415) 555-3695",
                    "type": "OTHER"
                }]
            }, {
                "id": "2",
                "displayName": "Daniel Higgins",
                "phoneNumbers": [{
                    "number": "555-478-7672",
                    "normalizedNumber": "555-478-7672",
                    "type": "HOME"
                }, {
                    "number": "(408) 555-5270",
                    "normalizedNumber": "(408) 555-5270",
                    "type": "MOBILE"
                }, {
                    "number": "(408) 555-3514",
                    "normalizedNumber": "(408) 555-3514",
                    "type": "OTHER"
                }]
            }, {
                "id": "3",
                "displayName": "John Paul Appleseed",
                "phoneNumbers": [{
                    "number": "888-555-5512",
                    "normalizedNumber": "888-555-5512",
                    "type": "MOBILE"
                }, {
                    "number": "888-555-1212",
                    "normalizedNumber": "888-555-1212",
                    "type": "HOME"
                }]
            }];
        }

答案 1 :(得分:0)

当您执行ID = myReader.IsDBNull(0) ? 0 : myReader.GetInt32(0);status = myReader.IsDBNull(1) ? string.Empty : myReader.GetString(1).Trim();时可能会发生这种情况,因为结果集不符合您的期望。您应该在实际阅读之前添加阅读器行的日志记录,这可能有助于您查明问题

答案 2 :(得分:0)

我猜问题是由myReader字段引起的,我认为这是静态的。如果你在https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader(v=vs.110).aspx查看SqlDataReader(我想这是字段的类型)文档,你会发现实例方法不是线程安全的,因此你必须同步访问该字段。

答案 3 :(得分:0)

plot(impact)捕获读者当时的价值并稍后处理。它不记得变量。必须如此,您可以从此示例中看到:using (myReader)。显然,C#语言在处置时不会重新执行该表达式。它只运行一次。

所以你要处理一些旧的/其他读者。

如果你在线程之间共享对象(可能使用静态变量),这很简单就是竞争条件。不要那样做。使用当地人。这里没有必要/优势使用静态变量。