gpt4 book ai didi

c# - 多线程 - 线程池是好的选择吗?

转载 作者:太空宇宙 更新时间:2023-11-03 19:25:31 25 4
gpt4 key购买 nike

我有一个导入数千个文件的 c#(.Net 3.5) 应用程序。现在,我为每个文件创建后台 worker 。它在一定限度内运行良好,然后应用程序因系统内存不足异常而终止。我假设这是由于大量线程而发生的。对于这种情况,线程池是一个好的解决方案吗?

异常(exception)是:

    System.OutOfMemoryException | Exception of type 'System.OutOfMemoryException' was thrown. 
at System.Data.RBTree`1.TreePage..ctor(Int32 size)
at System.Data.RBTree`1.AllocPage(Int32 size)
at System.Data.RBTree`1.InitTree()
at System.Data.Index.InitRecords(IFilter filter)
at System.Data.Index..ctor(DataTable table, Int32[] ndexDesc, IndexField[] indexFields,
Comparison`1 comparison, DataViewRowState recordStates, IFilter rowFilter)
at System.Data.DataTable.GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter
rowFilter)
at System.Data.DataColumn.get_SortIndex()
at System.Data.DataColumn.IsNotAllowDBNullViolated()
at System.Data.DataTable.EnableConstraints()
at System.Data.DataTable.set_EnforceConstraints(Boolean value)
at System.Data.DataTable.EndLoadData()
at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String
srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn
parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32
startRecord, Int32 maxRecords)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32
startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32
maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
at Dms.Data.Adapters.DataTableAdapterBase`2.FillByCommand(TTbl table, DbCommand command)

最佳答案

问题很可能是您尝试一次加载太多文件。

使用线程池可能会有所帮助,因为它可以为您提供一种限制处理的方法。但是,如果您正在导入和处理“数千个文件”,则适当的方法可能是创建一个管道来处理您的处理,然后用您的文件填充管道(或一定数量的管道)。这将使您能够控制并发量,并防止同时处理过多的单个文件。它可以将您的内存和处理要求保持在更合理的水平。


编辑:

自从您(现在)提到您正在使用 C#... BackgroundWorker 实际上确实使用了 ThreadPool。切换到直接使用线程池可能仍然是一个好主意,但它可能无法完全解决问题。您可能需要考虑使用类似 BlockingCollection<T> 的东西设置生产者/消费者队列。然后,您可以让 1 个或多个线程“使用”文件并处理它们,然后将所有文件添加到 BlockingCollection<T> .这将使您能够控制一次处理的文件数量(只要添加另一个线程即可进行处理)。

关于c# - 多线程 - 线程池是好的选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9023177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com