Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable.
Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.
Hi Francisco,
public class PgDataAccess
{
// Connection variables
private string connectionString = "";
private NpgsqlConnection sqlConnection = new NpgsqlConnection();
private bool Open()
{
try
{
if (sqlConnection.State == System.Data.ConnectionState.Closed)
sqlConnection.Open();
return true;
}
catch (Exception e)
{
Log.Warn(string.Format("PgDataAccess::Open(): Error openning DB, connection state: {0}, connection string: {1}",
sqlConnection.State.ToString(), ConnectionString.RemovePassword()), e);
return false;
}
}
/// <summary>
/// Closes database connection
/// </summary>
public void Close()
{
if (sqlConnection.State == System.Data.ConnectionState.Open)
sqlConnection.Close();
}
/// <summary>
/// Sets or gets Connection string, opens connection automatically on set
/// </summary>
public string ConnectionString
{
set
{
if (connectionString != value)
Close();
else
return;
connectionString = value;
sqlConnection.ConnectionString = connectionString.SetCommandTimeout(CommandTimeout);
if (Open())
{
GetFunctionsList();
GetAccountVariables();
}
}
get
{
return connectionString;
}
}
private NpgsqlParameter[] PrepareParameters(object[] parameters)
{
if (parameters == null || parameters.Length == 0)
return null;
NpgsqlParameter[] pgParameters = new NpgsqlParameter[parameters.Length];
for(int i = 0; i < parameters.Length; i++)
{
Type type;
if (parameters[i].IsDBNull())
type = System.DBNull.Value.GetType();
else
type = parameters[i].GetType();
pgParameters[i] = new NpgsqlParameter();
pgParameters[i].NpgsqlDbType = GetParameterType(type);
pgParameters[i].Value = parameters[i] ?? System.DBNull.Value;
}
return pgParameters;
}
}
I notice you are using a single connection tied to PgDataAccess and that you use this class as an static variable in your log class.
This means your code is very susceptible to thread concurrency issues which may cause you a lot of problems.
NpgsqlConnection isn't thread safe, just like other .net data providers.
I'd say your problems with the BufferedStream exception is caused by two or more threads trying to use the same connection at the same time.
I suggest you to open the connection and close it each time you use the connection, by relying in the internal Npgsql connection pooling. This will help you avoid a lot of concurrency problems.
If you still want to keep using a single connection through the lifetime of PgDataAccess, I think you should some serialization mechanism when accessing the NpgsqlConnection.
I think that after you make one of those changes: open and close a new NpgsqlConnection each time you are sending logging to Postgresql, or use some locking mechanism, your problems will disappear. I'd go with the first one which is simpler and the recommended way.
I tried locking on da, did not help, strange.