0

を使用してParallel.ForEach、新しいクラスを呼び出して作成しています。

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

MasterCrawlerClassとが含まれprivate static voidsていprivate 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 を完全には理解していません。

4

2 に答える 2

1

さて、あなたの質問はあまり明確ではありませんが、知りたいのは、あなたのクラス MasterCrawlerClass がスレッドセーフである (つまり、Parallel.ForEach() または複数のスレッドによってアクセスされる他のケースで安全に使用できる) ことです。 Parallel.ForEach() に渡すデリゲートで新しいインスタンスを作成します (つまり、各スレッドの新しいインスタンス)。

答え - 各スレッドがクラスの独自のインスタンスを持っている場合 - すべてのインスタンス (非静的) フィールドとプロパティは安全ですが、静的なものは必ずしも安全ではありません。それらを1回だけ割り当てる場合-それらが宣言されているとき、または静的コンストラクターで、その後のみそれらから読み取られる場合-OKである必要があります。ただし、静的メンバーに書き込む関数がある場合は、同時書き込みまたは読み書きを避けるために、このアクセスを同期する必要があります。同期に関する MSDN 情報は次のとおりです。「ロック」がニーズに合っているかどうかを確認してください。

あなたが提供したクラスには静的関数とプロパティしかないため、Parallel.ForEach で新しいインスタンスを作成する理由は明確ではありません。これらのプロパティはすべてクラスレベルであり、メモリ内の同じオブジェクトにつながり、しようとすると問題が発生します。異なるスレッドで静的関数を起動します (非同期同時アクセス)。

PS Note、いくつかのクラス(参照型)の静的フィールドまたはプロパティがあり、そのフィールド\プロパティの1つを書き込む場合-それでも安全ではありません-複数のスレッドがメモリの同じ部分を変更しようとしています。おそらく同時に、予測できない結果をもたらします.

于 2012-04-07T21:46:11.883 に答える
1

HTMLModelProcess はスレッドセーフです。アプリケーションの状態には影響しません。

SetNewProxy メソッドはスレッド セーフではありません。共有されている ProxyServer と ProxyPort の状態を変更します。この動作がインスタンス スコープで発生することが想定されている場合は、それ (および関連する状態) をインスタンスに移動する必要があります。

于 2012-04-07T21:31:56.500 に答える