I am attempting to query the database and pull excel files that could be as large as 1 million rows (~200MB) stored as varbinary
and pass it through a validator.
Our build server has 6GB of memory and a load-balanced processor and during runtime comes nowhere near maxing out the CPU or Memory.
Yet, after about 40 seconds the process throws an OutOfMemoryException
.
Here's the stack trace:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Data.SqlTypes.SqlBinary.get_Value()
at System.Data.SqlClient.SqlBuffer.get_ByteArray()
at System.Data.SqlClient.SqlBuffer.get_Value()
at System.Data.SqlClient.SqlDataReader.GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaData)
at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
at System.Data.SqlClient.SqlCommand.CompleteExecuteScalar(SqlDataReader ds, Boolean returnSqlValue)
at System.Data.SqlClient.SqlCommand.ExecuteScalar()
at eConfirmations.DataService.FileServices.FileDataService.GetFileContent(Guid fileId) in d:\w1\3\s\Source\eConfirmations.DataService\FileServices\FileDataService.cs:line 157
...
at System.Data.SqlTypes.SqlBinary.get_Value()
at System.Data.SqlClient.SqlBuffer.get_ByteArray()
at System.Data.SqlClient.SqlBuffer.get_Value()
at System.Data.SqlClient.SqlDataReader.GetValueFromSqlBufferInternal(SqlBuffer data, _SqlMetaData metaData)
at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
at System.Data.SqlClient.SqlCommand.CompleteExecuteScalar(SqlDataReader ds, Boolean returnSqlValue)
at System.Data.SqlClient.SqlCommand.ExecuteScalar()
at eConfirmations.DataService.FileServices.FileDataService.GetFileContent(Guid fileId) in d:\w1\3\s\Source\eConfirmations.DataService\FileServices\FileDataService.cs:line 157
And here's the my code that throws the exception:
private byte[] GetFileContent(Guid fileId)
{
byte[] content;
string connectionString = ConfigurationManager.ConnectionStrings["eConfirmationsDatabase"].ConnectionString;
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandTimeout = 300;
sqlCommand.CommandText = $"SELECT Content FROM dbo.[File] WHERE FileId = '{fileId}'";
sqlConnection.Open();
content = sqlCommand.ExecuteScalar() as byte[];
sqlConnection.Close();
sqlCommand.Dispose();
}
sqlConnection.Dispose();
}
return content;
}
Is there a more efficient way to pull back this data or can we update a setting on our build server to avoid this error?