5

静的クラス/メソッドに現在あるコードがいくつかありますが、それがスレッドセーフであることを確認したいと思いました。私が読んだことから、これは大丈夫だと思いますが、私の心の奥にある何かがそうではないかもしれないと言っています。私のWebページのデータ処理段階では、外部Webサービスを使用して注文レコードを作成しますが、これは非常に遅くなる可能性があります。おそらく30〜40秒から5分または10分(これは私の手に負えない)なので、起動します。リターンページをユーザーに戻し、新しいスレッドを開始し、処理が完了したらユーザーに電子メールを送信します。これは現在、静的クラス/メソッドにあります。すべてのオブジェクトが特定のメソッド内で作成されている場合(一般的なシステムのデフォルト値を除く)、そのメソッドはスレッドセーフである必要があります。だから、例えば、私が持っていた場合

public static class ProcessOrder()
{
    public static int GetOrderMaxSize()
    {
        return (....gets and parses ConfigurationManager.AppSettings["MaxOrderSize"]...);
    }

    public static bool CreateOrder(Order order)
    {
        XmlDocument xmlDoc = GetOrderXML(order);
        bool check = false;
        using (CreateOrderXML.Create xmlCo = new CreateOrderXML.Create())
        {
            xmlCo.Timeout = 60000;
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

            string xmlString = "";
            using (StringWriter stringWriter = new StringWriter())
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter))
                {
                    xmlDoc.WriteTo(xmlWriter);
                    xmlWriter.Flush();
                    xmlString = stringWriter.GetStringBuilder().ToString();
                }
            }

            byte[] bXMLOrder = encoding.GetBytes(xmlString);
            byte[] breturnMessage;

            check = xmlCo.Create(bXMLOrder, out breturnMessage);
            .... do something with return message
        }
        return check;
    }

    private static XmlDocument GetOrderXML(Order order)
    {
        ... creates an XML object for the order
    }
}

(CreateOrderXMLはWebサービスのURL /メソッドへのサービス参照です)特に長時間実行(主にxmlCo.Create(....)ステージ)の並行スレッドの場合、スレッドセーフでしょうか?クラスメンバーを入れ始めてメソッドで使用すると、異なるスレッドが値を上書きするという問題が確実に発生することを理解していますが、オブジェクトがメソッド内で作成されている限り、オブジェクトは問題ありません。彼ら?

4

2 に答える 2

13

そこで共有データにアクセスしているようには見えません。リモートリソースを要求し、このメソッドを実行するたびに一意のデータセットを構築します。そこで同期する必要はありません。

ここでのメソッドの実行ごとに、ローカル変数が作成されます。これは独自のコピーです。したがって、何も共有されていません。

于 2012-09-12T16:29:35.173 に答える
5

静的メソッドが静的(クラス)データにアクセスしない場合は、スレッドセーフである必要があります。考えられる唯一の競合点は、使用する可能性のある外部リソース(たとえば、ファイル、またはその他のシステムリソース)と、渡されるデータです。そして、そのような使用法のコンテキストを知っているのはあなただけです。

競合している可能性のあるそのようなものの使用法は、lockまたは他のプリミティブとシリアル化することができます。デッドロックを回避するために、同じ順序でリソースをシリアル化することを忘れないでください。リソースAとBを使用するメソッドが1つある場合:

lock( latch_a )
{
   process(object_a) ;
   lock ( latch_b )
   {
     process(object_a,object_b) ;
   }
}

逆を行う別の方法:

lock( latch_b )
{
   process(object_b) ;
   lock ( latch_a )
   {
     process(object_a,object_b) ;
   }
}

ある時点で、2つのスレッドがデッドロックし、それぞれがリソースを必要とする場合、他のスレッドがそのリソースへのアクセスを放棄する前に、他のスレッドが必要とします。

注:lock詳細については、ステートメント のC#ドキュメントを参照してください。一般に、ロックされたオブジェクトは、シリアル化されている共有リソースアクセスを表します(また、そうなる可能性があります)。一般的なパターンは、次のようなことを行うことです。

class Widget
{
   private static readonly object X = new object() ;

   public void Foo()
   {
     lock(X)
     {
       // Do work using shared resource
     }
     return ;
   }

}
于 2012-09-12T16:48:07.783 に答える