स्ट्रीमवाइटर का निपटान कहां करें यदि मुझे पूरे आवेदन जीवनकाल के दौरान इसकी ज़रूरत है?

Where to dispose StreamWriter if I need it during entire application lifetime? I'm going to dispose it in destructor, will that work? I have to dispose to flush data, and I don't want to use AutoFlush feature because from msdn: "You can get better performance by setting AutoFlush to false, assuming that you always call Close (or at least Flush) when you're done writing with a StreamWriter."

तो क्या मुझे नीचे दिए गए कोड में विनाशक में निपटान चाहिए?

class Log
{
    private static StreamWriter swLog = new StreamWriter("logMAIN.txt");

    static ~Log()
    {
        swLog.Dispose();
    }

    public static void Push(LogItemType type, string message)
    {
        swLog.WriteLine(type + " " + DateTime.Now.TimeOfDay + " " + message);
    }
}

upd instead of Dispose i meant to call Close but it is not improtant in this case because they seems doing exactly the same.

0
जोड़ा संपादित
विचारों: 1
यदि आप लॉगिंग के लिए ऐसा कर रहे हैं तो मौजूदा ट्रेसिंग फ्रेमवर्क का उपयोग करने पर विचार करें (एक जो नेट फ्रेमवर्क का हिस्सा है, या लॉग 4नेट जैसे बाहरी लोगों में से एक हो सकता है) जो पहले से ही आपके द्वारा मार रहे सभी मुद्दों को हल कर चुका है और भविष्य में खोजेगा (जैसे बहु-थ्रेड एक्सेस , लॉग रोटेशन, आईओ विफलताओं, विस्तारशीलता ...)।
जोड़ा लेखक Alexei Levenkov, स्रोत
बस File.WriteAllText का उपयोग करें और StreamWriter से परेशान न हों।
जोड़ा लेखक Bali C, स्रोत

2 उत्तर

आप एमएसडीएन से कुछ प्रदर्शन जानकारी पर फ्लश न करने का निर्णय ले रहे हैं। यह वह जगह नहीं है जहां मैं शुरू करूंगा।

क्या आपके पास साक्ष्य है जो ऑटोफ्लश का उपयोग करके आपको महत्वपूर्ण प्रदर्शन समस्याओं का कारण बनता है?

क्या आपने इन प्रदर्शन समस्याओं को एक अलग तरीके से कम करने पर विचार किया है, उदा। StreamWriter पर एक एकल धागा लिखना, या तो ऑटो-फ्लशिंग या आवधिक रूप से प्रत्येक 20 सेकंड या जो भी हो रहा है?

आपने हमें यह नहीं बताया है कि आप किस प्रकार का आवेदन लिख रहे हैं, आपको याद रखें - इससे शटडाउन के बारे में आप कितना जानते हैं इसके संदर्भ में महत्वपूर्ण अंतर हो सकता है।

यह भी ध्यान रखें कि आपके द्वारा दिया गया कोड थ्रेड-सुरक्षित नहीं है। आप एक साथ कई थ्रेड से StreamWriter का उपयोग कर समाप्त कर सकते हैं; मुझे संदेह है कि StreamWriter विशेष रूप से उस परिदृश्य के लिए डिज़ाइन किया गया है।

0
जोड़ा
कुछ लॉग बहुप्रचारित हैं, मैं इस मामले में लॉक (यह) के अंदर पुश विधि का उपयोग कर रहा हूं। मुझे लगता है कि मैं पृष्ठभूमि धागे का उपयोग नहीं करता (लेकिन मैं कार्य का उपयोग कर रहा हूं। धन्यवाद जॉन मुझे लगता है कि मैं बस AutoFlush का उपयोग करूंगा जब तक कि यह कोई समस्या न हो जाए
जोड़ा लेखक javapowered, स्रोत
यह सिर्फ कंसोल आवेदन है
जोड़ा लेखक javapowered, स्रोत
मैं इतनी सरल चीज़ क्यों नहीं कार्यान्वित कर सकता हूं: "बाहरी वर्ग का निपटारा होने तक स्ट्रीमराइटर खोलें। बाहरी वर्ग का निपटारा करते समय डिस्क पर सब कुछ फ्लश करें"।
जोड़ा लेखक javapowered, स्रोत
आवेदन एचएफटी व्यापार के लिए प्रयोग किया जाता है। ठीक है हाँ, जब मैं एप्लिकेशन बंद करता हूं तो केवल बाहर निकलता हूं :) या निकास बिंदु से आपका क्या मतलब है?
जोड़ा लेखक javapowered, स्रोत
मेरे अनुप्रयोगों में मेरे पास कई अलग-अलग लॉग हैं, उनमें से कुछ, इस के रूप में, केवल एक थ्रेड से उपयोग किया जाता है। शायद AutoFlush सुविधा मेरे लिए ठीक रहेगी, लेकिन मुझे तुरंत लॉग की आवश्यकता नहीं है, इसलिए मैं इसका उपयोग न करने की सोच रहा था। AutoFlush का उपयोग करने के लिए मेरे पास कोई कारण नहीं है और यह डिफ़ॉल्ट रूप से .NET में बंद हो गया है इसलिए मैंने "डिफ़ॉल्ट" परिदृश्य का उपयोग करने का निर्णय लिया।
जोड़ा लेखक javapowered, स्रोत
@javapowered: "ऑटोफ्लश का उपयोग करने के लिए मेरे पास कोई कारण नहीं है" - ठीक है, इस तथ्य के अलावा कि आप यह सुनिश्चित करना चाहते हैं कि आपका ऐप बंद होने पर भी कोई लॉग न खोएं? आप अभी भी ने समझाया नहीं है कि आप किस प्रकार का ऐप लिख रहे हैं, और क्या आपके पास एक अच्छी तरह से परिभाषित निकास बिंदु है ...
जोड़ा लेखक Jon Skeet, स्रोत
@javapowered: आप कर सकते हैं। लेकिन आपने हमें यह नहीं बताया है कि ऐप का kind क्या है - वेब ऐप, समृद्ध ग्राहक इत्यादि। यदि आप अपने लॉग का निपटान करने के लिए सही समय बता सकते हैं, तो सुनिश्चित करें - तब उनका निपटान करें।
जोड़ा लेखक Jon Skeet, स्रोत
@javapowered: ठीक है, अंत में, कुछ जानकारी। और क्या आपके पास एकाधिक धागे हैं, या यह सब सिर्फ एक धागा है? यदि आपके पास एकाधिक धागे हैं, तो उनमें से कोई पृष्ठभूमि धागे हैं? यदि आप बाहर निकलने के दौरान कर सकते हैं बस सबकुछ साफ तरीके से निपटाना, यह सबसे आसान तरीका होगा ... हालांकि इसका मतलब यह है कि आपको शायद IDisposable सभी तरह से चुपके मिलेंगे लॉगिंग के लिए, बस अपने कोड के माध्यम से। मैं अभी भी आपको कम से कम विचार बस ऑटो-फ्लशिंग करने का आग्रह करता हूं ...
जोड़ा लेखक Jon Skeet, स्रोत

समस्या वास्तव में StreamWriter प्रारंभ करने का तरीका है। इस तरह एक नियमित वस्तु का उपयोग करना

using (var logger = new Log())
{
    app.Run();
}

StreamWriter अभी भी लॉग वर्ग में एक स्थिर फ़ील्ड हो सकता है, लेकिन एक स्थिर प्रारंभकर्ता का उपयोग करने के बजाय समय में ज्ञात बिंदुओं पर प्रारंभ और निपटान किया जाता है।

इसके लिए आपको काम करने के लिए आपको IDisposable इंटरफ़ेस को लागू करने के लिए क्लास लॉग करने की आवश्यकता होगी और StreamWriter को इस तरह से निपटान विधि में निपटाना होगा:

class Log: IDisposable
{
    private static StreamWriter swLog;

    public Log()
    {
       swLog = new StreamWriter("logMAIN.txt");
    }

    public void Dispose()
    {
        swLog.Dispose();
    }

    public static void Push(LogItemType type, string message)
    {
        swLog.WriteLine(type + " " + DateTime.Now.TimeOfDay + " " + message);
    }
}

यह भी ध्यान दें कि अपवाद फेंकने पर भी लॉग का निपटारा किया जाएगा।

0
जोड़ा
और यदि मेरे पास कई (या दर्जन) अलग-अलग लॉग हैं तो मुझे बहुत से नेस्टेड <�कोड> ब्लॉक का उपयोग करना चाहिए?
जोड़ा लेखक javapowered, स्रोत
@JonSkeet मेरे बुरे, चलो बस static को विनाशक से हटा दें और मान लें कि इस वर्ग का उपयोग केवल एक धागे से किया जाता है ... एचएम हालांकि मुझे बहुप्रचारित संस्करण की भी आवश्यकता है
जोड़ा लेखक javapowered, स्रोत
@ vidstige: मूल कोड भी संकलित नहीं होगा, क्योंकि स्थिर स्थिरता जैसी कोई चीज़ नहीं है। लेकिन एक समाधान का सुझाव देना जो एक स्थैतिक चर निर्माण पर एक अच्छा जवाब नहीं है, आईएमओ है।
जोड़ा लेखक Jon Skeet, स्रोत
@ vidstige: वास्तव में, अब यह बदतर है। अब यदि आपके पास दो थ्रेड में अलग-अलग उदाहरण बनाते हुए ब्लॉक ब्लॉक का उपयोग कर रहे हैं, तो आप एक थ्रेड में StreamWriter का निपटान कर सकते हैं, जबकि आप इसे दूसरे में उपयोग करने का प्रयास कर रहे हैं। आउच। जाहिर है कि यदि आपका ऐप एक अच्छी तरह से नियंत्रित निकास बिंदु के लिए पर्याप्त सरल है, तो सवाल मामूली है। मैं कल्पना करता हूं कि यह मामला नहीं है, हालांकि ओपी ने यह नहीं कहा है कि यह किस प्रकार का ऐप है।
जोड़ा लेखक Jon Skeet, स्रोत
@javapowered: अब आप मान रहे हैं कि अंतर्निहित धारा के लिए अंतिमकर्ता से पहले आपका अंतिमकर्ता निष्पादित किया जाएगा। इसकी कोई गारंटी नहीं है। असल में, आपको इस मामले में फाइनलाइजर्स का उपयोग नहीं करना चाहिए।
जोड़ा लेखक Jon Skeet, स्रोत
आपने कैसे स्ट्रीमवाइटर को "समय में ज्ञात बिंदुओं पर प्रारंभ और निपटान" समझाया नहीं है - जहां निपटान यहां महत्वपूर्ण बिंदु है।
जोड़ा लेखक Jon Skeet, स्रोत
@ जोन मूल कोड में भी समस्या है। याद रखें कि फाइनलर अपने धागे में चलता है। एकाधिक धागे से पहुंच का सवाल केवल स्ट्रीमवाइटर को निपटाने के लिए जब प्रश्न से संबंधित है। मेरी धारणा विपरीत है जैसा आपने अनुमान लगाया है, एप्लिकेशन में एक अच्छी तरह से परिभाषित निकास बिंदु है।
जोड़ा लेखक vidstige, स्रोत
@ जोन सच है। संपादन के बाद उम्मीद है कि वह हिस्सा थोड़ा और स्पष्ट है
जोड़ा लेखक vidstige, स्रोत
हां क्यों नहीं? या एक नई कक्षा बनाएं जिसमें लॉग की एक सूची है जो निपटान हो जाती है जब it का निपटारा किया जाता है। एक वर्ग, एक जिम्मेदारी।
जोड़ा लेखक vidstige, स्रोत