2012-04-09 14 views
5

que tienen un bucle Parallel.Foreacherror multihilo: Ya hay un DataReader abierto asociado con esta conexión que debe estar cerrada primera

var options = new ParallelOptions(); 
options.MaxDegreeOfParallelism = 1; 
Parallel.ForEach(urlTable.AsEnumerable(),drow => 
{ 
    using (var WCC = new MasterCrawlerClass()) 
    { 
     WCC.MasterCrawlBegin(drow); 
    } 
} 

Este bucle llama a la clase y recorre todos mis DataRows, sin embargo cada uno de esos datarows hacen un relleno DataTable o un comando de actualización a un DB MySQL. El código que tengo para ambos está abajo.

private static DataTable DTTable(string mysqlQuery, string queryName) 
{ 
    DataTable DTTableTable = new DataTable(); 
    try 
    { 
     MySqlDataAdapter DataDTTables = new MySqlDataAdapter(mysqlQuery, MySQLProcessing.MySQLStatic.Connection); 
     DataTable DataDTTablesDT = new DataTable(); 
     DataDTTables.SelectCommand.CommandTimeout = 240000; 
     DataDTTables.Fill(DataDTTablesDT); 
     DTTableTable = DataDTTablesDT; 

    } 
    catch (Exception ex) 
    { 

     GenericLogging("Failed MySQLquery: " + ex.Message.ToString(), "MySQLProcessor", "DTTable", "", "MysqlError", "", queryName, mysqlQuery); 

    } 
    return DTTableTable; 
} 
private static void MySQLInsertUpdate(string MySQLCommand, string mysqlcommand_name) 
{ 
    try 
    { 
     MySqlCommand MySQLCommandFunc = new MySqlCommand(MySQLCommand, MySQLProcessing.MySQLStatic.Connection); 
     MySQLCommandFunc.CommandTimeout = 240000; 
     MySQLCommandFunc.ExecuteNonQuery(); 
    } 
    catch (Exception ex) 
    { 
     GenericLogging("Failed MySQLquery: " + ex.Message.ToString(), "MySQLProcessor", "DTTable", "", "MysqlError", "", mysqlcommand_name, MySQLCommand); 
    } 
} 

la cosa es CMI contiene 10 o más huecos, cada uno de estos huecos accede a las funciones de MySQL al menos una vez. Entonces, si el bloqueo es la respuesta, ¿es posible crear 1 función de bloqueo para todos los vacíos? ¿Si es así, cómo? Si hay otra manera, por favor hágamelo saber

¡Gracias!

bien como lo sugiere Consolidé las preguntas

El código ahora se ha actualizado para reflejar bloqueo, por favor ver más abajo.

static readonly object _object = new object();

public static DataTable DTTable(string mysqlQuery, string queryName) 
     { 
      lock (_object) 
      { 
       DataTable DTTableTable = new DataTable(); 
       try 
       { 
        using (MySqlDataAdapter DataDTTables = new MySqlDataAdapter(mysqlQuery, MySQLProcessing.MySQLStatic.Connection)) 
        { 
         using (DataTable DataDTTablesDT = new DataTable()) 
         { 
          DataDTTables.SelectCommand.CommandTimeout = 240000; 
          DataDTTables.Fill(DataDTTablesDT); 
          DTTableTable = DataDTTablesDT; 
          DataDTTables.Dispose(); 
         } 
        } 

       } 
       catch (Exception ex) 
       { 

        GenericLogging("Failed MySQLquery: " + ex.Message.ToString(), "MySQLProcessor", "DTTable", "", "MysqlError", "", queryName, mysqlQuery); 

       } 
       return DTTableTable; 
      } 
     }

Este es el único código que llama el DataReader, ¿cómo puede haber dos lectores de datos abiertas si hay una cerradura?

+0

Si no me equivoco, el problema está en el método que devuelve DataTable, no en el que devuelve vacío. Puede implementar un grupo de conexiones para evitar el problema. – phoog

Respuesta

2

El problema es que los proveedores de datos ADO.NET generalmente no permiten más de un lector de datos abierto a la vez por conexión. SQL Server tiene el concepto de multiple active result sets (MARS), pero hasta donde sé, MySQL aún no lo admite.

Es probable que deba especificar una conexión diferente a MySQLProcessing.MySQLStatic.Connection. No hay nada que te impida usar más de una conexión. El problema aquí es que las conexiones son recursos caros, por lo que se supone que debes usarlos con moderación.

0

Está utilizando la misma conexión al mismo tiempo.

¿Tiene varios hilos? Porque parece que 2 subprocesos usan la misma conexión para realizar una llamada al mismo tiempo.

+0

tiene la razón, pero puse un candado en el vacío así que, ¿cómo podría llamarlo mientras está bloqueado? –

+1

No hay ningún candado en el código pegado arriba. Pero, ¿estás seguro de que es el único método donde usas esta conexión? Además, puede crear varias conexiones, es de bajo costo, ya que .NET tiene un grupo de conexión y no crea una nueva conexión si ya hay una disponible. – Fabske

+0

Suspiro ... He votado a favor de cerrar este y el código con bloqueo es http://stackoverflow.com/questions/10081513/c-sharp-there-is-already-an-open-datareader-associated-with-this -conexión-whi –

Cuestiones relacionadas