OutOfMemoryException が発生しないように、プロセスで使用可能なメモリを取得しようとしています。インターネットを検索したところ、メモリを使用しているが利用できない方法の例がいくつか見つかりました。
ユースケースを提供しましょう...
一括挿入を行っているプロセスがあります (SqlBulkCopy を使用)。メソッドに aDataTable
を渡しています。失敗時にプロセスを再試行できるようにする必要がWriteToServer
あるため、a を使用できません。DataReader
私が最初に考えたのは、一度に挿入する任意の行数、たとえば 50,000 行を選択することでした。しかし、これはデータを知らない一般的なプロセスです。列の数も各行のデータ量もわかりません。そのため、に行を追加しているときにメモリを監視し、メモリが不足しそうにDataTable
なったときにそれを投稿できると考えていましたSqlBulkCopy
。
これは有効なアプローチですか、それともより良い方法がありますか?
これが有効なアプローチである場合、利用可能なメモリの量を決定するためにどの関数を使用しますか?
これまでの私のコードは次のとおりです...これAvailableMemoryIsLow
は、私が判断する方法を理解できないものです。
// m_buffer is a read-once cache (implements IDataReader) that pulls
// data from an external source as needed so it uses very little memory.
// My original implementation just used m_buffer as the parameter of
// WriteToServer but now I have to add retry logic into the process.
DataTable dataTable = new DataTable(m_tableName);
foreach (DataField d in m_buffer.GetColumns())
dataTable.Columns.Add(new DataColumn(d.FieldName, d.FieldType));
while (m_buffer.Read())
{
DataRow row = dataTable.NewRow();
for (int i = 0; i < m_buffer.FieldCount; i++)
row[i] = m_buffer.GetValue(i);
dataTable.Rows.Add(row);
// How do I determine AvailableMemoryIsLow
if (rowCount++ >= 50000 || AvailableMemoryIsLow)
{
PutDataIntoDatabase(dataTable);
dataTable.Clear();
rowCount = 0;
}
}
if (dataTable.Rows.Count > 0)
PutDataIntoDatabase(dataTable);