c# स्थगित करने के लिए एक स्थान स्ट्रिंग बदलने से मेरा लॉगर क्लास टूट जाता है



multithreading mono (1)

यहां अंतर है:

निर्माण फ़ाइलों के मेटाडेटा में बनाए जाते हैं, इसलिए जब आप वर्ग चलाते हैं, तो मान पहले से ही वहां है।

पढ़ें केवल संकलन के समय में आरम्भ किया जाता है, आपके मामले में, चाल को सुनता है, भले ही आपने पहले पथ को घोषित कर दिया, फिर भी कम्पाइलर ने म्यूट एक्स ऑब्जेक्ट को पहले आरम्भ किया, यहाँ क्यों है:

आरंभ करने के लिए आपका पहला स्थिर ऑब्जेक्ट लकड़हारा है:

public static readonly TimingLogger Logger = new TimingLogger();

चूंकि आपने कन्स्ट्रक्टर को बुलाया है, गैर स्थैतिक सदस्यों को आरम्भिक किया जाता है, आरंभ करने वाले अगले सदस्य को म्यूट एक्स बनाते हैं। इस बिंदु पर आपने अभी तक पथ को शुरू नहीं किया है, इसलिए आप अपने म्यूट एक्स ऑब्जेक्ट्स को गलत और रिक्त पैरामीटर के साथ बना रहे हैं।

यदि आप एक ही त्रुटि चाहते हैं कि आपके पास केवल पढ़ने के साथ const के साथ है, तो आप एक स्थैतिक निर्माता का उपयोग करके अपने स्थैतिक मापदंडों को प्रारंभ करने के क्रम को मजबूर कर सकते हैं जैसे:

static TimingLogger()
{
    path = "C:\\Logs\\TimingLog.txt";
    Logger = new TimingLogger();
}

या बस लॉगगर से पहले पथ डाल

यदि आप कॉन्स्ट का उपयोग करते हुए त्रुटि नहीं करना चाहते हैं, तो बस शून्य पैरामीटर का उपयोग करके म्यूट एक्स प्रारंभ करें:

private readonly Mutex mutex = new Mutex(false, null);

https://code.i-harness.com

मैं एक ऐसी समस्या के साथ संघर्ष कर रहा हूं जो हाल ही में एक सरल लॉग-टाइल क्लास के साथ मैंने लिखा था।

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Assets.Code
{
    class TimingLogger
    {
        public static readonly TimingLogger Logger = new TimingLogger();
        private static readonly string path = "C:\\Logs\\TimingLog.txt";
        private readonly Mutex mutex = new Mutex(false, path);
        private StreamWriter writer;
        private readonly Queue<string> queue = new Queue<string>();
        private bool isRunning;
        private readonly object obj = new object();

        private TimingLogger()
        {

        }

        public void CheckPath()
        {
            if (!File.Exists(path))
            {
                File.Create(path);
            }
        }

        public void Run()
        {
            isRunning = true;
            while (isRunning)
            {
                lock (obj)
                {
                    while (queue.Count <= 0)
                    {
                        Monitor.Wait(obj);
                    }
                    Log(queue.Dequeue());
                }
            }
        }

        public void Log(string line)
        {
            try
            {
                mutex.WaitOne();
                writer = File.AppendText(path);
                writer.WriteLine(line);
                writer.Close();
            }
            catch (Exception)
            {
                //throw;
            }
            finally
            {
                mutex.ReleaseMutex();
            }
        }

        public void Enqueue(string line)
        {
            lock (obj)
            {
                queue.Enqueue(line);
                Monitor.Pulse(obj);
            }
        }

        public void Stop()
        {
            isRunning = false;
        }
    }
}

यह क्लास अभी तक ठीक काम कर रहा था, जब मैंने देखा कि मेरी लॉग फ़ाइल मुझे अपेक्षित डेटा नहीं दिखा रही थी अजीब तरह से, मैंने कक्षा की किसी भी कार्यक्षमता को नहीं बदला है। मेरे नए एक के साथ एक पुरानी, ​​कार्यशील संस्करण की तुलना में, फर्क सिर्फ इतना था कि मेरे कुछ फ़ील्ड private और readonly बनाए गए थे। इसके अलावा, string path को const को बदल दिया गया था और मेरी पूरी घबराहट के लिए, इस मुद्दे को readonly लिए इसे वापस बदलने के लिए मैंने जो मुद्दा उठाया था।

तो मेरा सवाल है: पृथ्वी पर यह कैसे संभव है? जहां तक ​​मुझे पता है, इस स्थिति में पढ़ने के लिए और const में कोई फ़र्क नहीं होना चाहिए।

डीबगिंग करते समय, व्यवहार में परिवर्तन काफी महत्वपूर्ण होता है, खासकर Run() विधि में। यहाँ क्या होना चाहिए कि एक बार Log(queue.Dequeue()); को बुलाया गया है, धागा lock स्टेटमेंट को छोड़ देगा और फिर से while (isRunning) पाश के माध्यम से पुनरावृत्त होगा। यह बहुत स्पष्ट है, सही लगता है? हालांकि, जब मैं string path को const और डिबग करने के लिए फिर से Log(queue.Dequeue()); , Log(queue.Dequeue()); एक बार पारित किया जाता है और लॉग फ़ाइल में एक भी कथन पाया जा सकता है, उसके बाद यह केवल फिर से कुछ भी नहीं करता है यह दोबारा while (isRunning) फिर से while (isRunning) फिर से नहीं आ रहा है और यह lock (obj) ब्लॉक छोड़ने में प्रतीत नहीं होता है। लॉगर थ्रेड को बंद करने के बाद सफलतापूर्वक Log(queue.Dequeue()); बंद करने या बंद करने के लिए लगता है Log(queue.Dequeue()); एक बार।

असल में Log विधि में अपवाद फेंकने में कोई फर्क नहीं पड़ता, कोई भी अपवाद नहीं फेंक दिया जाता है क्योंकि लॉगिंग ठीक काम करता है

मुझे यह बताना चाहिए कि मैं इस कोड का उपयोग यूनिटी 3 डी 5 के साथ कर रहा हूँ, जो मोनो का उपयोग करता है लेकिन फिर भी, इस तरह के एक छोटे से संपादन के व्यवहार में इस कठोर बदलाव मेरे लिए असंभव लगता है क्या कोई यह समझा सकता है कि ऐसा क्यों हो रहा है?

धन्यवाद!





readonly