2008-09-18 11 views
6

लॉक करने की आवश्यकता है एएसपीनेट वेब एप्लिकेशन में, मैं एक फ़ाइल को लिखना चाहता हूं। यह फ़ंक्शन पहले डेटाबेस से डेटा प्राप्त करेगा, और उसके बाद फ्लैट फ़ाइल लिखें।किसी फ़ाइल को लिखना चाहते हैं, लेकिन संभावित रूप से कई लेखकों को एक बार में,

यह सुनिश्चित करने के लिए मैं क्या कर सकता हूं कि केवल 1 लेखन होता है, और एक बार लिखने के बाद, अन्य धागे जो शायद फ़ाइल में लिखना चाहते हैं, लेखन के बाद से नहीं होते हैं।

मैं यह लिखना चाहता हूं केवल अगर यह 15 मिनट में नहीं किया गया है।

मुझे पता है कि एक लॉक कीवर्ड है, तो क्या मुझे सब कुछ लॉक में लपेटना चाहिए, फिर जांचें कि इसे 15 मिनट या उससे अधिक में अपडेट किया गया है या वीज़ा बनाम?

अद्यतन

कार्यप्रवाह:

चूंकि यह एक वेब अनुप्रयोग है, कई उदाहरण एक विशेष वेब पेज को देखने वाले लोगों की जाएगी। मैं कैश सिस्टम में निर्माण का उपयोग कर सकता हूं, लेकिन अगर एएसपीनेट रीसायकल करता है तो कैश को पुनर्निर्माण करना महंगा होगा, इसलिए मैं इसे एक फ्लैट फ़ाइल में लिखना चाहता हूं। मेरा दूसरा विकल्प सिर्फ विंडोज़ सेवा बनाने के लिए होगा, लेकिन यह प्रबंधन करने के लिए और अधिक काम है जो मैं चाहता हूं।

+0

क्या सभी लेख एक ही एप्लिकेशन के एक उदाहरण के भीतर हो रहे हैं? या क्या आवेदन के कई उदाहरण एक ही समय में लिखने का प्रयास करेंगे या अलग-अलग एप्लिकेशन एक ही समय में लिखने का प्रयास करेंगे? –

उत्तर

2

किसी साझा ऑब्जेक्ट को लॉक करने के लिए अपने लेखन कोड को सिंक्रनाइज़ करें ताकि ब्लॉक के अंदर केवल एक थ्रेड हो। अन्य इंतजार करते हैं जब तक कि वर्तमान में बाहर निकल जाए।

lock(this) 
{ 
    // perform the write. 
} 

अपडेट: मुझे लगता है कि आपके पास साझा ऑब्जेक्ट है। यदि ये एक ही मशीन पर अलग-अलग प्रक्रियाएं हैं, तो आपको नामांकित म्यूटेक्स की तरह कुछ चाहिए। Looky here for an example

+0

मुझे लगता है कि यह काम नहीं करेगा, कारणों से मैंने नीचे समझाया है। – MarkR

1

क्या पूरे उदाहरण के बजाय ऑब्जेक्ट वैरिएबल को लॉक करना बेहतर नहीं है?

0

मुझे विश्वास नहीं है कि .NET की लॉकिंग विभिन्न प्रक्रियाओं पर लागू होती है। इसके अलावा, लॉक (यह) केवल अन्य थ्रेड को बाहर कर देगा जो "इस" के समान उदाहरण पर विधि चला रहे हैं - इसलिए अन्य प्रक्रियाओं में भी एक ही प्रक्रिया में अलग-अलग उदाहरणों पर एक बार चल सकता है।

मान लें कि आपकी सभी प्रक्रियाएं उसी मशीन पर चल रही हैं, फ़ाइल लॉकिंग हालांकि इसे करना चाहिए।

यदि आप अलग-अलग मशीनों पर हैं, तो आपका माइलेज भिन्न हो सकता है- Win32 का दावा है कि नेटवर्क लॉकिंग जो नेटवर्क पर काम करती है, लेकिन ऐतिहासिक रूप से अनुप्रयोग जो इस पर भरोसा करते हैं (एमएसएएसी सोचें) को फाइल भ्रष्टाचार के साथ समस्याएं हैं।

+0

आप सही हैं कि लॉक काम करने के लिए, आपको "इस" के एक ही उदाहरण का उपयोग करने के लिए सभी विधियों की आवश्यकता होगी। यहां समाधान ** स्थिर ** डमी ऑब्जेक्ट उदाहरण बनाने के लिए हो सकता है जो यह सुनिश्चित करेगा। –

0
// try enter will return false if another thread owns the lock 
    if (Monitor.TryEnter(lockObj)) 
    { 
     try 
     { 
     // check last write time here, return if too soon; otherwise, write 
     } 
     finally 
     { 
     Monitor.Exit(lockobj); 
     } 
    } 
+0

जो लॉक (lockObj) {} जैसी सटीक चीज है। –

1

फ़ाइल I/O ऑपरेशन जो फ़ाइल को लिखते हैं, स्वचालित रूप से फ़ाइल को लॉक कर देंगे। जांचें कि फ़ाइल लॉक है (लिखने की कोशिश करके) और यदि यह नहीं लिखता है। कोई भी लिखने से पहले, फ़ाइल पर टाइमस्टैम्प जांचें और देखें कि यह 15 मिनट से अधिक है या नहीं।

afaik आप विंडोज़/जो कुछ भी लॉक किए बिना फ़ाइल में नहीं लिख सकते हैं।

अब आपके लिए जो कुछ बचा है, यह देखना है कि एमएसडीएन का उपयोग करके उपरोक्त कैसे करें (क्षमा करें, मुझे इसे सब देखने के लिए परेशान नहीं किया जा सकता है और मुझे सी # कक्षाएं बहुत अच्छी तरह याद नहीं हैं)। :)

+1

नोट, मेरा उत्तर टाइमस्टैम्प पर भरोसेमंद होने पर निर्भर करता है - हमेशा एक अच्छी धारणा नहीं। जो भी प्रक्रिया लिखने को समाप्त करती है, उसके बाद आप 15 मिनट तक लिखे नहीं जा रहे फ़ाइल को खोल सकते हैं। :) – jheriko

0

उपयोग फ़ाइल-प्रणाली ताले

की तरह दूसरों का सुझाव दिया,।इस स्थिति में नेट ताले सीमित उपयोग होंगे।

FileInfo fi = new FileInfo(path); 
if (fi.Exists 
    && (DateTime.UtcNow - fi.LastWriteTimeUtc < TimeSpan.FromMinutes(15)) { 
    // file is fresh 
    return; 
} 

FileStream fs; 
try { 
    fs = new FileStream(
    path, FileMode.Create, FileAccess.Write, FileShare.Read); 
} catch (IOException) { 
    // file is locked 
    return; 
} 

using (fs) { 
    // write to file 
} 

इस धागे और प्रक्रियाओं में काम करेगा: यहाँ कोड है।

0

आपको लोगों को Mutex पर विचार करना चाहिए। यह एकाधिक धागे और प्रक्रियाओं के बीच सिंक्रनाइज़ कर सकता है।

संबंधित मुद्दे