简体   繁体   中英

There is already an open datareader - Mysql - C# I dispose of connection

This one is driving me insane, and i can't figure out why it's throwing this error.

Here is my Program.cs

MySQLProcessor.Connection = MySQLProcessor.OpenCon();
        MySQLProcessor.ThreadingConnection = MySQLProcessor.OpenCon();
        DataTable All_Websites_DataTable =  MySQLProcessor.DTTable("select BaseURL,subURL from CouponExtractor.tblUrls where GroceryStoreBit = b'0'",MySQLProcessor.Connection);
        MySQLProcessor.Connection.Dispose();
Semaphore _pool = new Semaphore(1, 50);
        Parallel.ForEach(All_Websites_DataTable.AsEnumerable(), website_DataRow =>
        {
            _pool.WaitOne();
            //additional_subURL is used to crawl threw additional URLs until unqiue value is hit
            int additional_subURL = 0;
            Catch_Old_Values = false;

            string baseURL = All_Websites_DataTable.ItemArray[0].ToString();
            string subURL = All_Websites_DataTable.ItemArray[1].ToString();
            string complete_url = string.Empty;

            //need a bool to check homepage without crawling subpages
            bool check_homepage = true;
            complete_url = baseURL + "/" + subURL.Replace("@", additional_subURL.ToString());
            string mysqlquery_siteprocesslog = "insert into tbllogs(message,timestampcolumn) Values('Processing: " + complete_url + "',Now())";
            MySQLProcessor.MySQLInsertUpdate(mysqlquery_siteprocesslog,MySQLProcessor.ThreadingConnection);

            //as long as catch_old_values is false, the app will continue crawling the website until it hits an old value
            while (Catch_Old_Values == false)
            {
                additional_subURL++;


                if (additional_subURL >= 7)
                {
                    Catch_Old_Values = true;
                    break;
                }
                else if (check_homepage == true)
                {
                    //set check_homepage to false because we will crawl the homepage and dont want to do it again.
                    check_homepage = false;
                    SiteProcessing.ProcessSite(baseURL, baseURL);


                }
                else
                {
                    complete_url = baseURL + "/" + subURL.Replace("@", additional_subURL.ToString());
                    SiteProcessing.ProcessSite(complete_url, baseURL);
                }

            }
            _pool.Release();
        });

For length of post sake here is the only section of SiteProcessing that accesses MysqlProcessor

 if (hotitem == true)
                    {
                        string mysqlquery_InserthotResults = "insert into couponextractor." + targetTable + " (BaseURL,Description,realURL,TimeStampcolumn,uniqueKey,hotkey) Values ('" + baseURL + "','" + description.Replace("'", "") + "','" + realURL + "',Now(),'" + uniqueKey.Replace("'", "") + "','" + hotitemkey + "')";
                        MySQLProcessor.MySQLInsertUpdate(mysqlquery_InserthotResults, MySQLProcessor.ThreadingConnection);
                    }
                    else
                    {
                        string mysqlquery_InsertResults = "insert into couponextractor." + targetTable + " (BaseURL,Description,realURL,TimeStampcolumn,uniqueKey) Values ('" + baseURL + "','" + description.Replace("'", "") + "','" + realURL + "',Now(),'" + uniqueKey.Replace("'", "") + "')";
                        MySQLProcessor.MySQLInsertUpdate(mysqlquery_InsertResults, MySQLProcessor.ThreadingConnection);
                    }

And here is Mysqlprocessor

public static MySqlConnection Connection { get; set; }
    public static MySqlConnection ThreadingConnection { get; set; }
    public static MySqlConnection OpenCon()
    {
        MySqlConnection masterOpenCON = new MySqlConnection("removed for privacy");
        masterOpenCON.Open();
        return masterOpenCON;
    }

    public static DataTable DTTable(string mysqlQuery, MySqlConnection MysqlCon)
    {
        DataTable DTTableTable = new DataTable();
        using (MysqlCon)
        {
            using (MySqlDataAdapter DataDTTables = new MySqlDataAdapter(mysqlQuery, MysqlCon))
            {
                DataDTTables.SelectCommand.CommandTimeout = 2500;
                using (DataTable DataDTTablesDT = new DataTable())
                {
                    DataDTTables.Fill(DataDTTablesDT);
                    DTTableTable = DataDTTablesDT;
                    DataDTTablesDT.Dispose();
                }

            }
        }

        return DTTableTable;
    }

    public static void MySQLInsertUpdate(string MySQLCommand, MySqlConnection MysqlCon)
    {
        try
        {
            using (MysqlCon)
            {
                MySqlCommand MySQLCommandFunc = new MySqlCommand(MySQLCommand, MysqlCon);
                MySQLCommandFunc.CommandTimeout = 2500;
                MySQLCommandFunc.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            if (ex.Message.ToString().Contains("Duplicate entry"))
            {
                //SiteController.Catch_Old_Values = true;
            }
            else if (ex.Message.ToString().Contains("Data too long for column"))
            {


            }
            else
            {
                EventLog.WriteEntry("CouponCrawler", ex.Message.ToString(), EventLogEntryType.Error);
            }
        }
    }

I'm so confused, I clearly Dispose of MySQLProcessor.Connection in Program.CS before i even enter the Threading. And then I never call a datareader in the rest of the app. Any help is welcomed i'm going insane..

The exception is being thrown here:

using (MysqlCon)
            {
                MySqlCommand MySQLCommandFunc = new MySqlCommand(MySQLCommand, MysqlCon);
                MySQLCommandFunc.CommandTimeout = 2500;
                MySQLCommandFunc.ExecuteNonQuery();
            }

A 'using' statement is going to dispose the object once execution leaves the body of the using statement. In your foreach loop you're going to dispose your connection the first time you call MySQLInsertUpdate.

Also (and the reason for your exception), is that by doing a parallel foreach you will execute two queries at the same time on the same connection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM