C#Parallel.Foreach,New Class和Static voids./strings

时间:2012-04-07 21:04:52

标签: c#

我正在使用Parallel.ForEach来调用并创建一个新类。

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

MasterCrawlerClass包含private static voidsprivate static string。我想我的问题是这个。由于我在foreach中调用了一个新课程,因此该新课程实例中的所有voids / strings都安全吗?

class MasterCrawlerClass : IDisposable
{
    public void Dispose()
    {
        GC.Collect();
    }
    public static void SetNewProxy()
    {
        string mysql_Proxyserver_ProxyPort = "select ProxyServer,ProxyPort,ResponseTime FROM proxies.tblproxies where Active = 1 and DateTested >= Date_sub(CurDate(),INTERVAL 2 day) and ResponseTime <= 3 order by Rand() limit 1";
        DataTable proxyDT = new DataTable();
        proxyDT = DTTable(mysql_Proxyserver_ProxyPort, "mysql_Proxyserver_ProxyPort");
        ProxyServer = proxyDT.Rows[0].ItemArray[0].ToString();
        ProxyPort = Convert.ToInt32(proxyDT.Rows[0].ItemArray[1].ToString());
    }

    private static string HTMLModelProcess(string inputString)
    {
        string returnString = string.Empty;
        string ModelString = inputString.Replace("Certified", "").Replace("Used", "").Trim();
        string[] makeModelSplit = ModelString.Split(new char[] { ' ' }, 4);
        returnString = makeModelSplit[2];
        return returnString;

    }
    private static string ProxyServer { get; set; }
    private static int ProxyPort { get; set; }

}

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

MysqlProcessing.Mysqlstatic.Connection在Parallel之前设置,永远不会改变。

还有一些voids还有一些strings。我还没完全理解Threading,所以我正试图通过它。

2 个答案:

答案 0 :(得分:1)

您的HTMLModelProcess是线程安全的。它不会影响任何应用程序状态。

SetNewProxy方法不是线程安全的。它会更改共享的ProxyServer和ProxyPort的状态。如果应该在实例范围内发生此行为,则应将其(以及相关状态)移动到实例。

答案 1 :(得分:1)

好吧,你的问题不是很清楚,但你想知道AFAIU是你的类MasterCrawlerClass线程安全(即可以安全地与Parallel.ForEach()或其他情况一起使用它是由多个线程访问的)只要在委托中创建一个传递给Parallel.ForEach()的新实例(即每个线程的新实例)。

答案 - 如果每个线程都有自己的类实例 - 所有实例(非静态)字段和属性都是安全的,但不一定是静态的。如果你只分配它们一次 - 当它们被声明时或者在静态构造函数中并且之后只读取它们 - 它应该没问题。但是,如果您有一个函数或函数写入静态成员 - 应该同步此访问以避免同时写入或读写。 Here is MSDN info info on synchronization - see if "locking" suits your needs.

由于您提供的类只有静态函数和属性 - 它不清楚,为什么在Parallel.ForEach中创建一个新实例 - 所有这些属性都是类级别,并且会导致内存中的相同对象,如果您尝试在不同的线程上启动静态函数(非同步并发访问)。

P.S。注意,如果你有一个类的静态字段或属性(引用类型)并写一个字段\属性 - 它仍然不安全 - 几个线程试图改变同一块内存,可能同时和不可预测的结果。