.NET

2008-09-23 14 views
6

में वेब सेवा में एकल फ़ाइल को लिखना जारी करना मैंने .NET 2.0, C# में एक webservice बनाया है। वेब सेवा क्लाइंट द्वारा जब भी विभिन्न विधियों को बुलाया जाता है तो मुझे फ़ाइल में कुछ जानकारी लॉग इन करने की आवश्यकता होती है।.NET

समस्या तब आती है जब एक उपयोगकर्ता प्रक्रिया फ़ाइल पर लिख रही है और दूसरी प्रक्रिया इसे लिखने का प्रयास करती है।

The process cannot access the file because it is being used by another process.

समाधान है कि मैं सी # में लागू करने की कोशिश की और विफल रहे हैं के रूप में नीचे हैं: मैं निम्नलिखित त्रुटि मिलती है।

  1. कार्यान्वित सिंगलटन कक्षा जिसमें फ़ाइल में लिखने वाले कोड शामिल हैं।
  2. फ़ाइल में लिखने वाले कोड को लपेटने के लिए प्रयुक्त लॉक स्टेटमेंट।
  3. मैंने ओपन सोर्स लॉगर लॉग 4नेट का उपयोग करने का भी प्रयास किया है, लेकिन यह एक आदर्श समाधान भी नहीं है।
  4. मुझे सिस्टम इवेंट लॉगर में लॉगिंग करने के बारे में पता है, लेकिन मेरे पास यह विकल्प नहीं है।

मैं जानना चाहता हूं कि ऐसी समस्या का एक पूर्ण और पूर्ण समाधान मौजूद है या नहीं?

उत्तर

10

लॉकिंग शायद असफल हो रही है क्योंकि आपकी webservice एक से अधिक कार्यकर्ता प्रक्रिया द्वारा चलाया जा रहा है। आप एक नामित म्युटेक्स, जो प्रक्रियाओं में साझा किया जाने के साथ उपयोग की रक्षा कर सकता है, ताले के विपरीत आप lock(someobject) {...} का उपयोग करके मिलती है:

Mutex lock = new Mutex("mymutex", false); 

lock.WaitOne(); 

// access file 

lock.ReleaseMutex(); 
+0

म्यूटेक्स लॉकोब = = नया म्यूटेक्स (झूठा, "mymutex"); संकलित करेगा –

+0

आपको इसे बनाने से पहले पहले उस नाम के साथ मौजूदा म्यूटेक्स खोलने का प्रयास करना चाहिए। अन्यथा, "नई म्यूटेक्स (...)" रेखा एक अपवाद फेंक सकती है। मैं एक कोशिश/पकड़/आखिरकार ब्लॉक का उपयोग करने की सलाह भी दूंगा, रिलीज कॉल को आखिरकार ब्लॉक में ले जाउंगा, और अगर आपको वास्तव में लॉक मिल जाए तो इसे छोड़ दें। –

0

शायद फ़ाइल में लिखने के लिए एक प्रकार की "कतार रेखा" लिखें, इसलिए जब आप फ़ाइल को लिखने का प्रयास करते हैं तो यह देखने के लिए जांच करता रहता है कि फ़ाइल लॉक है या नहीं, अगर यह है - यह प्रतीक्षा करता है, अगर यह नहीं है बंद नहीं है - फिर इसे लिखें।

0

आप परिणामों को एक एमएसएमक्यू कतार में धक्का दे सकते हैं और एक विंडोज़ सेवा कतार से वस्तुओं को चुन सकती है और उन्हें लॉग कर सकती है। यह थोड़ा भारी है, लेकिन यह काम करना चाहिए।

0

जोएल और चार्ल्स। यह जल्दी था! :)

जोएल: जब आप "कतार रेखा" कहें तो क्या आप एक अलग थ्रेड बनाते हैं जो कतार की जांच करने के लिए एक लूप में चलता है और साथ ही फ़ाइल को लॉक नहीं होने पर लिखता है?

चार्ल्स: मैं MSMQ और खिड़कियों सेवा संयोजन के बारे में पता है, लेकिन जैसे मैंने कहा कि मैं वेब सेवा :)

धन्यवाद pradeep_tp

0

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

संभवतः सबसे आसान काम ग्लोबल.एक्सएक्स में एप्लिकेशन शुरू होने के दौरान धागा बनाना होगा और यह सिंक्रनाइज़ इन-मेमोरी कतार (System.Collections.Generics.Queue) को सुन सकता है। थ्रेड खोलें और फ़ाइल हैंडल के जीवनकाल का मालिक बनें, केवल वह धागा फ़ाइल को लिख सकता है।

एएसपी में क्लाइंट अनुरोध क्षणिक रूप से कतार को लॉक कर देंगे, नए लॉगिंग संदेश को कतार पर दबाएंगे, फिर अनलॉक करें।

लॉगर थ्रेड कतार पर समय-समय पर कतार का मतदान करेगा - जब संदेश कतार पर पहुंचते हैं, तो थ्रेड फ़ाइल में डेटा को पढ़ और प्रेषित करेगा।

1

आप यह नहीं कहते कि आपकी वेब सेवा कैसे होस्ट की जाती है, इसलिए मुझे लगता है कि यह आईआईएस में है। मुझे नहीं लगता कि फ़ाइल को कई प्रक्रियाओं तक एक्सेस किया जाना चाहिए जब तक कि आपकी सेवा एकाधिक एप्लिकेशन पूल में नहीं चलती। फिर भी, मुझे लगता है कि आपको यह त्रुटि मिल सकती है जब एक प्रक्रिया में एकाधिक थ्रेड लिखने की कोशिश कर रहे हैं।

मुझे लगता है कि मैं आपके द्वारा सुझाए गए समाधान के लिए जाऊंगा, प्रदीप, एक ही ऑब्जेक्ट बनाएं जो लॉग फ़ाइल में सभी लेखन करता है। उस ऑब्जेक्ट के अंदर मेरे पास एक कतार होगी जिसमें लॉग इन करने के लिए सभी डेटा लिखे जाएंगे। मेरे पास इस कतार से अलग थ्रेड पढ़ने और लॉग फ़ाइल में लिखना होगा। आईआईएस जैसे थ्रेड-पूल होस्टिंग पर्यावरण में, यह एक और धागा बनाने के लिए बहुत अच्छा प्रतीत नहीं होता है, लेकिन यह केवल एक है ... ध्यान रखें कि इन-मेमोरी कतार आईआईएस रीसेट नहीं टिकेगी; आईआईएस प्रक्रिया घटने पर आप कुछ प्रविष्टियां खो सकते हैं जो "इन-फ्लाइट" हैं।

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

0

पता करने के लिए क्या मैं अपने कोड में करने के लिए कोशिश कर रहा हूँ निम्नलिखित singletone वर्ग मैं सी # में लागू कर दिया है है

सार्वजनिक सील वर्ग FileWriteTest {

private static volatile FileWriteTest instance; 

private static object syncRoot = new Object(); 

private static Queue logMessages = new Queue(); 

private static ErrorLogger oNetLogger = new ErrorLogger(); 

private FileWriteTest() { } 

public static FileWriteTest Instance 
{ 
    get 
    { 
     if (instance == null) 
     { 
      lock (syncRoot) 
      { 
       if (instance == null) 
       { 
        instance = new FileWriteTest(); 
        Thread MyThread = new Thread(new ThreadStart(StartCollectingLogs)); 
        MyThread.Start(); 

       } 
      } 
     } 

     return instance; 
    } 
} 

private static void StartCollectingLogs() 
{ 

    //Infinite loop 
    while (true) 
    { 
     cdoLogMessage objMessage = new cdoLogMessage(); 
     if (logMessages.Count != 0) 
     { 
      objMessage = (cdoLogMessage)logMessages.Dequeue(); 
      oNetLogger.WriteLog(objMessage.LogText, objMessage.SeverityLevel); 

     } 
    } 
} 

public void WriteLog(string logText, SeverityLevel errorSeverity) 
{ 
    cdoLogMessage objMessage = new cdoLogMessage(); 
    objMessage.LogText = logText; 
    objMessage.SeverityLevel = errorSeverity; 
    logMessages.Enqueue(objMessage); 

} 

}

जब मैं इस कोड को डीबग मोड में चलाएं (केवल एक उपयोगकर्ता का उपयोग सिम्युलेट करता है), मुझे उस रेखा पर "स्टैक ओवरफ़्लो" त्रुटि मिलती है जहां कतार रुक जाती है।

नोट: उपरोक्त कोड में त्रुटिLogger एक कक्षा है जिसमें फ़ाइल को लिखने के लिए कोड है। objMessage लॉग संदेश ले जाने के लिए एक इकाई वर्ग है।

+0

अस्थिरता का उपयोग क्यों करें, अगर आपको यह नहीं पता कि इसका उपयोग कैसे किया जाए? ; पी – leppie

0

वैकल्पिक रूप से, आप डेटाबेस में त्रुटि लॉगिंग करना चाह सकते हैं (यदि आप उपयोग कर रहे हैं)

0

Koth,

मैं Mutex ताला, जो "ढेर अतिप्रवाह" त्रुटि हटा दिया गया है लागू किया है। इससे पहले कि मैं निष्कर्ष निकाल सकूं कि यह सभी मामलों में ठीक काम कर रहा है या नहीं, मुझे अभी भी लोड परीक्षण करना है।

मैं वेबसाइटों में से एक में म्यूटेक्स ओबेट्स के बारे में पढ़ रहा था, जो कहता है कि म्यूटेक्स प्रदर्शन को प्रभावित करता है। मैं म्यूटेक्स के माध्यम से ताला लगाकर एक चीज़ जानना चाहता हूं।

मान लीजिए कि उपयोगकर्ता प्रक्रिया 1 फ़ाइल पर लिख रही है और साथ ही उपयोगकर्ता प्रक्रिया 2 उसी फ़ाइल को लिखने का प्रयास करती है। चूंकि Process1 ने कोड ब्लॉक पर लॉक लगाया है, प्रोसेस 2 कोशिश करेगा या पहले प्रयास के बाद बस मर जाएगा।

धन्यवाद pradeep_tp

+0

Process2 प्रक्रिया समाप्त होने तक प्रतीक्षा करेगा। इसे कम करने के लिए, लॉक के बाहर जितना संभव हो उतना करें। – Khoth

0

तक म्युटेक्स जारी किया गया है यह इंतजार करेंगे ....

0

Joel: When you say "queue line" do you mean creating a separate thread that runs in a loop to keep checking the queue as well as write to a file when it is not locked?

हाँ, यह मूल रूप से मैं क्या सोच रहा था। एक और धागा है जिसमें थोड़ी देर लूप हो, जब तक कि यह फ़ाइल तक पहुंच न सके और बचाएं, फिर समाप्त करें।

लेकिन आपको इसे ऐसे तरीके से करना होगा जहां पहली धागा दिखने लगती है, पहले पहुंच प्राप्त हो जाती है। यही कारण है कि मैं कतार कहता हूं।

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

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