【问题标题】:index out of range exception when using tasks使用任务时索引超出范围异常
【发布时间】:2014-05-17 02:45:11
【问题描述】:

当我在数组列表上使用异步任务时,出现“索引超出范围”异常。我检查了整个stackoverflow并尝试了不同的方法,但它们都不起作用。也许我错过了一些东西......有人可以建议。

        Task[] dataTasks = (from eachRow in ppcRowsCollection.Rows
                            select CreateDataRows(eachRow, subcTableArray, rowsArrayWithDefaultAndCommonValues)).ToArray();

private async Task<DataRow[]> CreateDataRows(PpcRow givenPpcRow, DataTable[] subcTableArray, DataRow[] rowsArrayWithDefaultAndCommonValues)
{
    return await Task.Run(() =>
    {
        DataTable[] subcTableArrayLocal = subcTableArray;
        DataRow[] defaultRowsArray = GetrowsArrayWithDefaultAndCommonValues(ref subcTableArrayLocal, ref rowsArrayWithDefaultAndCommonValues);
        SetOtherThanCommonColumnValues(ref defaultRowsArray, givenPpcRow);
        return defaultRowsArray;
    }
    ).ConfigureAwait(false);
}

private DataRow[] GetrowsArrayWithDefaultAndCommonValues(ref DataTable[] subcTableArray, ref DataRow[] rowsArrayWithDefaultAndCommonValues)
{
    DataRow[] defaultRowsArray = subcTableArray.Select(x => x.NewRow()).ToArray(); //This is where I am getting EXCEPTION

    DataRow[] defaultRowsArrayCopy = defaultRowsArray;

    foreach (DataRow row in defaultRowsArrayCopy)
    {
        row.ItemArray = rowsArrayWithDefaultAndCommonValues
                            .Where(x => x.Table.TableName == row.Table.TableName)
                            .First()
                            .ItemArray;
    }
    return defaultRowsArrayCopy;
}

堆栈跟踪:

在 System.ThrowHelper.ThrowArgumentOutOfRangeException() 在 System.Collections.Generic.List1.get_Item(Int32 index) at System.Data.RecordManager.NewRecordBase() at System.Data.DataTable.NewRecord(Int32 sourceRecord) at System.Data.DataTable.NewRow(Int32 record) at System.Data.DataTable.NewRow() at PedWebService.<GetrowsArrayWithDefaultAndCommonValues>b__21(DataTable x) in c:\Work\src\PedWebService.cs:line 2913 at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() 在 System.Linq.Buffer1..ctor(IEnumerable1 来源)在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 源)在 PedWebService.GetrowsArrayWithDefaultAndCommonValues(DataTable[]& subcTableArray, DataRow[]& rowsArrayWithDefaultAndCommonValues) in c:\Work\src\PedWebService.cs:2913 行

【问题讨论】:

  • 您能否将异常的堆栈跟踪添加到问题中?这应该提供更多的洞察力。
  • 感谢瑞恩调查。这是堆栈跟踪。
  • 尝试添加一个变量并将其值设置为subcTableArray.Select(x =&gt; x.NewRow())。看起来这可能为空。下次您可以在询问之前尝试使用更简单的示例重现问题。
  • 我尝试添加变量并存储 subcTableArray.Select(x => x.NewRow()) 的值。它不为空。它确实有价值,我在调用异步方法之前创建它。
  • 您想要完成的总体目标是什么?

标签: c# task-parallel-library task async-await


【解决方案1】:

您在同一张桌子上并行调用DataTable.NewRow()DataTable 不是线程安全的,这就是它不起作用的原因。

如果您被DataTable 卡住,我认为最好的选择是根本不使用并行化。

您也可以尝试仅锁定有问题的操作(调用NewRow()),但我不确定这是否足以使代码线程安全。

【讨论】:

  • 谢谢 svick。就是这样。一旦我锁定了 DataTable,就可以正常工作。不幸的是,我坚持使用数据表并且没有选择。在 MSDN 上,我还注意到数据表的线程安全性“这种类型对于多线程读取操作是安全的。您必须同步任何写入操作”。 msdn.microsoft.com/en-us/library/…
猜你喜欢
  • 2017-12-16
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
  • 2023-04-10
相关资源
最近更新 更多