[英]Ensuring Thread-Safety On Static Methods In C#
我有一些我目前在靜態類/方法中的代碼,但我想檢查它是否是線程安全的。 從我讀過的內容來看,我認為這應該沒問題,但我腦子里的一些事情卻說它可能不是。 我的網頁的數據處理階段使用外部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(....)階段)並發線程? 我明白,如果我開始使用類成員然后在方法中使用它們,這肯定會引入不同線程覆蓋值的問題,但只要在方法中創建對象,它們應該沒問題,應該'他們?
它看起來不像你在那里訪問任何共享數據; 您正在請求遠程資源,並在每次執行此方法時構建一組唯一的數據。 那里不需要同步。
這里方法的每次執行都是創建局部變量 - 它是自己的副本。 所以什么都沒有被分享。
如果靜態方法不訪問任何靜態(類)數據,則它應該是線程安全的。 唯一可能的爭用點是它可能使用的外部資源(例如文件或其他系統資源),以及傳入的數據。只有您知道這種用法的上下文。
可能在爭用中的事物的使用可以用lock
或其他靈長類動物來序列化。 不要忘記以相同的順序序列化資源,以免死鎖。 如果您有一個使用資源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它可以放棄對所述資源的訪問。
編輯注意:有關詳細信息,請參閱lock
語句的C#文檔。 通常,鎖定的對象表示(並且可能是)正在序列化的共享資源訪問。 一個常見的模式是做類似的事情:
class Widget
{
private static readonly object X = new object() ;
public void Foo()
{
lock(X)
{
// Do work using shared resource
}
return ;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.