The following line of code sometimes results in "Specified cast is not valid" exception:

public static object Select(string sql, OleDbTransaction dbt)
{
  try
  {
     OleDbCommand cmd = new OleDbCommand(sql, lib.dbc, dbt);
     object obj = cmd.ExecuteScalar(); /* <- this is what fails */
     return obj;
  }
  catch (Exception ex)
  {
    /* deleted code - error message to the user */
    return null;
  }
}

This function is executed several times in the program before it fails. If fails olny when it's executed in a new execution thread, and then only sometimes. When I call the part of the program which performs processing in a thread, and it calls this function, either it works all the time (=> I click the button, it executes, no error, I click and execute again and again...), or it never works (=> I click the button and execute, exception, I click and execute again, exception again...).

lib.dbc -> static variable of type OleDbConnection initialized only at program startup and used very often throughout the code, valid

I have no idea how to debug it any further, and above all, what assignment to a variable of type object can fail? ExecuteScalar should return object or null. Database I'm using is Jet (MS Access).

In the exception I find this stack trace, maybe it can help:

at System.Data.OleDb.OleDbConnection.IOpenRowset()
at System.Data.OleDb.OleDbCommand.ExecuteTableDirect(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteScalar()
at FK.sql.Select(String sql, OleDbTransaction dbt)
有帮助吗?

解决方案

If fails olny when it's executed in a new execution thread, and then only sometimes.

This statement, combined with the fact you're passing in the connection as a parameter, suggests you may be trying to use the same database connection, and maybe transaction, on multiple threads.

Don't: instead create a new connection each time you want to access the database: connection pooling means that this will be efficient.

其他提示

Try this, just as a diagnostic tool:

public static object Select(string sql, OleDbTransaction dbt)
{
  try
  {
     using (OleDbConnection con = new OleDbConnection(lib.dbc.ConnectionString))
     using (OleDbCommand cmd = new OleDbCommand(sql, con, dbt))
     {
         object obj = cmd.ExecuteScalar();
         return obj;
     }
  }
  catch (Exception ex)
  {
    /* deleted code - error message to the user */
    return null;
  }
}

This may help determine whether you have a threading problem.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top