确保线程安全的静态方法在C#(Ensuring Thread-Safety On Static Me

2019-09-22 08:32发布

我有一些代码,我现在有一个静态类/方法,但我想检查,这将是线程安全的。 从我读过什么,我想这应该是确定的事,但在我心中的背面说这可能不是。 我的网页的数据处理阶段使用外部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(....)阶段)的并发线程? 我明白,如果我开始把在课堂上的成员,然后在该方法中使用它们,这肯定会引入不同的线程改写值的问题,但只要对象方法中创建的,他们应该是好的,不该” Ť他们?

Answer 1:

它看起来并不像你所访问的任何共享的数据存在; 您请求远程资源,建设一套独特数据的使用这种方法的每次执行。 有没有必要进行同步出现。

这里的方法,每执行创建本地变量 - 它自己的拷贝。 所以,没有什么是永远被共享。



Answer 2:

如果您的静态方法不访问任何静态(类)的数据,它应该是线程安全的。 争论的唯一可能的点会是在通过外部资源,它可能会使用(文件,例如,或其他系统资源),和数据。只有你知道那种用法的情况下。

的这样的事情,可能是在争夺使用可序列化枝条lock或其他primatives。 不要忘了,免得你死锁序列化资源以相同的顺序。 如果您有使用资源A和B中的一个方法:

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

在某些时候,你的两个线程死锁,当他们每个人都需要一个资源的其他需求bofore它可以放弃访问所述资源。

编辑要注意:在查看C#文档lock的细节陈述。 通常,锁定对象表示(并且可能),以正被序列化的共享资源的访问。 一个常见的模式是做这样的事情:

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

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

}


文章来源: Ensuring Thread-Safety On Static Methods In C#