2012-04-09 11 views
5

を閉じる必要があります。この接続に関連付けられているオープンのDataReaderが既にあり、私はこのループは、しかし、それぞれのクラスを呼び出し、すべての私でDataRowをループParallel.Foreachループにマルチスレッド・エラー:最初の

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

を持っていますこれらのデータローは、DataTableを満たすか、またはMySQL DBに対して更新コマンドを実行します。これらの両方のコードは以下のとおりです。

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

事はWCCが10かそこらの空隙を含んでいる、これらの空隙のそれぞれは、少なくとも一度はMySQLの機能にアクセスします。したがって、ロックが答えであれば、すべてのボイドに対して1つのロック関数を作成できますか?もしそうなら、どのように?別の方法がある場合は、私に教えてください

ありがとう!提案されているよう

オーケー、私はコードは今のロックを反映するように更新されている質問

を統合し、下記を参照してください。

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

このロックがある場合、DataReaderを呼び出すコードだけが、どのように2人のオープンデータの読者があることができますか?

+0

私が間違っていない場合、問題は、voidを返すものではなく、DataTableを返すメソッドにあります。問題を回避するために接続プールを実装することがあります。 – phoog

答えて

2

問題は、ADO.NETデータプロバイダは、一般に、接続ごとに一度に複数のオープンデータリーダーを許可しないことです。 SQL Serverはmultiple active result sets (MARS)という概念を持っていますが、私が知っている限り、MySQLはそれをまだサポートしていません。

おそらくMySQLProcessing.MySQLStatic.Connection以外の別の接続を指定する必要があります。複数の接続を使用することを妨げるものは何もありません。ここでの問題は、接続が高価なリソースであるため、あまり使用しないことになっていることです。

0

あなたは同じ接続を同時に使用しています。

複数のスレッドがありますか? 2つのスレッドが同時に同じ接続を使用して呼び出しを行うように見えるためです。

+0

あなたは正しいですが、私はvoidにロックを入れていますので、ロックされている間はどのように呼び出すことができますか –

+1

上記のコードにはロックがありません。しかし、あなたはこの接続を使用する唯一の方法だと確信していますか?また、いくつかの接続を作成することができます。これは、.NETに接続プールがあり、すでに使用可能な場合は新しい接続を作成しないため、低コストです。 – Fabske

+0

一言...私はこれを閉じるために投票しました。ロック付きのコードはhttp://stackoverflow.com/questions/10081513/c-sharp-there-is-already-an-open-datareader-associated-with-thisです。 -connection-whi –

関連する問題