2012-04-09 10 views
5

mam pętlę Parallel.Foreachbłąd Wielowątkowość: Jest już otwarty DataReader skojarzony z tym połączeniem, które muszą być zamknięte pierwszy

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

Pętla ta wywołuje klasę i pętle za pośrednictwem wszystkich moich wierszy DataRows, jednak każdy z te pliki danych albo wypełniają DataTable, albo wykonują polecenie aktualizacji do MySQL DB. Kod, który mam dla obydwu, znajduje się poniżej.

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); 
    } 
} 

Rzecz WCC zawiera 10 lub tak pustych przestrzeni, przy czym wszystkie puste przestrzenie uzyskuje dostęp do funkcji MySQL co najmniej raz. Więc jeśli blokowanie jest odpowiedzią, czy jest możliwe utworzenie 1 funkcji blokowania dla wszystkich pustek? Jeśli tak to jak? Jeśli jest inny sposób, proszę dać mi znać

Dzięki!

Ok jak sugerowano i skonsolidowane pytania

Kod został obecnie aktualizowane w celu odzwierciedlenia zamek, można znaleźć poniżej.

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; 
      } 
     }

To jest tylko kod, który wywołuje DataReader, jak może istnieć dwie otwarte czytniki danych, jeśli istnieje blokada?

+0

Jeśli się nie mylę, problemem jest metoda, która zwraca DataTable, a nie tę, która zwraca pustkę. Możesz zaimplementować pulę połączeń, aby ominąć problem. – phoog

Odpowiedz

2

Problem polega na tym, że dostawcy danych ADO.NET na ogół nie zezwalają na więcej niż jeden otwarty czytnik danych w czasie połączenia. SQL Server ma koncepcję multiple active result sets (MARS), ale o ile wiem, MySQL jeszcze jej nie obsługuje.

Prawdopodobnie konieczne będzie określenie innego połączenia niż MySQLProcessing.MySQLStatic.Connection. Nic nie powstrzyma cię od korzystania z więcej niż jednego połączenia. Problem polega na tym, że połączenia są drogimi zasobami, więc powinieneś ich używać oszczędnie.

0

Używasz tego samego połączenia w tym samym czasie.

Czy masz kilka wątków? Ponieważ wydaje się, że 2 wątki używają tego samego połączenia do jednoczesnego wykonywania połączenia.

+0

masz rację, ale włożyłem blokadę w pustkę, więc jak to się mogło dzwoni, gdy jest zablokowana? –

+1

Nie ma blokady w powyższym kodzie. Ale czy jesteś pewien, że to jedyna metoda, w której używasz tego połączenia? Można również utworzyć kilka połączeń, które są tanie, ponieważ .NET ma pulę połączeń i nie tworzy nowego połączenia, jeśli jest już dostępne. – Fabske

+0

Westchnienie ... Głosowałem, aby zamknąć ten kod, a kod z zamkiem to http://stackoverflow.com/questions/10081513/c-sharp-there-is-already-an-open-datareader-pisany-z-tym- -connection-whi –

Powiązane problemy