को तोड़ने के लिए एक स्थान स्ट्रिंग को बदलना मैं हाल ही में एक साधारण लोगोफाइल क्लास के साथ पॉप अप करने वाली किसी समस्या के साथ संघर्ष कर रहा हूं।मेरे लॉगर वर्ग
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
पर बदलकर मेरे द्वारा जारी किए गए मुद्दे को ठीक किया गया।
तो मेरा सवाल है: पृथ्वी पर यह कैसे संभव है? जहां तक मुझे पता है, इस स्थिति में केवल पढ़ने और दृढ़ता के बीच कोई अंतर नहीं होना चाहिए।
डीबगिंग करते समय, व्यवहार में परिवर्तन पर्याप्त है, खासकर Run()
विधि में। होना चाहिए कि यहां एक बार Log(queue.Dequeue());
कहा गया है, थ्रेड lock
कथन छोड़ देगा और फिर से while (isRunning)
लूप के माध्यम से फिर से चला जाएगा। यह बहुत स्पष्ट लगता है, है ना? हालांकि, जब मैं string path
को const
में बदलता हूं और फिर से डीबग करता हूं, तो Log(queue.Dequeue());
एक बार पास हो जाता है और लॉग फ़ाइल में एक ही कथन पाया जा सकता है, जिसके बाद यह कभी भी कुछ और नहीं करता है। यह while (isRunning)
से पहले नहीं आया है और ऐसा लगता है कि यह lock (obj)
ब्लॉक नहीं छोड़ता है। Log(queue.Dequeue());
सफलतापूर्वक कॉल करने के बाद लॉगर थ्रेड बस बंद या रोकना प्रतीत होता है।
वास्तव में Log
विधि में अपवाद फेंकने से कोई फर्क नहीं पड़ता, कोई अपवाद नहीं फेंक दिया जाता है क्योंकि लॉगिंग स्वयं ठीक काम करती है।
मुझे यह उल्लेख करना चाहिए कि मैं इस कोड का उपयोग यूनिटी 3 डी 5 के साथ कर रहा हूं, जो मोनो का उपयोग करता है। लेकिन फिर भी, इस तरह के एक छोटे से संपादन द्वारा व्यवहार में यह कठोर परिवर्तन मेरे लिए असंभव लगता है। क्या कोई यह समझा सकता है कि यह क्यों हो रहा है?
धन्यवाद!
मैंने सोचा कि यह संदेश के मुख्य भाग लेकिन ठीक अंदर पोस्ट करने के लिए थोड़ा बहुत ज्यादा कोड था, मैंने इसे जोड़ा है। – David
यह एक लिंक से बहुत बेहतर है जो गायब हो सकता है और बाद में आपके प्रश्न को समझ में नहीं आता है। एक लॉगर लिखना एक मुश्किल व्यवसाय है जिसे पहले ही हल कर लिया गया है। मौजूदा समाधान का उपयोग करना बेहतर नहीं होगा जैसे कि [nLog] (http://nlog-project.org/)? – spender
मजेदार है कि आपको इसका जिक्र करना चाहिए, मैंने एनएलओजी की कोशिश की लेकिन मुझे यूनिटी 3 डी 5 के साथ काम करने में कुछ समस्याएं आईं। बस दोहराने के लिए, मेरा लॉगर ठीक काम करता है कि मैंने समस्या को ठीक और ठीक कर दिया है। मैं बस समस्या को समझ नहीं पा रहा हूं। – David