2012-12-13 10 views
5

मैं बहुप्रचारित एप्लिकेशन (एक सर्वर) पर काम कर रहा हूं जो मूल रूप से एक कंसोल एप्लिकेशन है। जिसमें मैं प्रसंस्करण लॉग को कंसोल पर दिखाता हूं जो डिफ़ॉल्ट रूप से सफेद रंग में होता है। लेकिन सफल लेनदेन पर मैं पाठ को हरे रंग में और असफल लेनदेन पर दिखाता हूं, मैं लाल रंग में टेक्स्ट दिखाता हूं। इसलिए इसके लिए Program.cs में मेरे पास तीन अलग-अलग फ़ंक्शन हैं।मल्टीथ्रेड किए गए अनुप्रयोगों में ठीक से काम नहीं कर रहे कंसोल रंग बदलना

सरल लॉग

public static void Write(string text) 
{ 
     try 
     { 
      Console.Out.Write(text); 
     } 
     catch (Exception) 
     { } 
    } 

असफल लेनदेन मैं लाल करने के लिए रंग बदलने के लिए, तो सफेद

public static void WriteError(string text) 
    { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine("\t" + text); 
     Console.ForegroundColor = ConsoleColor.White; 
    } 

सफल लेनदेन के लिए करने के लिए प्रिंट और फिर वापस मैं हरे रंग की है, तो प्रिंट और उसके बाद करने के लिए रंग बदलने वापस सफेद

public static void WriteSuccess(string text) 
    { 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.WriteLine("\t" + text); 
     Console.ForegroundColor = ConsoleColor.White; 

    } 

समस्या तब होती है जब 200 से अधिक ग्राहक con nected और प्रत्येक ग्राहक के लेनदेन का लॉग कंसोल पर प्रिंटिंग है। और जब मैं सिंगल लाइन के लिए हरे रंग की तरह रंग बदलता हूं तो यह सामान्य लॉग की कई अन्य रेखाओं को हरे रंग में भी बनाता है। तो कृपया मुझे बताएं कि मैं इस समस्या को कैसे हल कर सकता हूं।

Console.ForegroundColor = ConsoleColor.Red; 
    Console.WriteLine("\t" + text); 

आप रंग, एक और धागा बीच में आता है, सेट कुछ और करने के लिए रंग सेट और फिर आप पाठ (गलत रंग में) मुद्रित:

+0

मुझे लगता है कि आपको – AMember

उत्तर

8

अपने समस्या है।

आपको एक लॉक के साथ खंड की रक्षा के लिए की जरूरत है:

static object lockObj = new object(); 

public static void WriteError(string text) 
{ 
    lock(lockObj) 
    { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine("\t" + text); 
     Console.ForegroundColor = ConsoleColor.White; 
    } 
} 

एक ही बात आप के लिए WriteSuccess(...)

+0

लॉक करने की आवश्यकता हो सकती है क्या थ्रेड को सीधे कंसोल में लिखने में सक्षम होना अच्छा विचार है? – adripanico

+0

यह ऑब्जेक्ट करेगा कि मुझे लॉक करना होगा? –

+0

मैंने पढ़ा है कि कंसोल। राइटलाइन() थ्रेड सुरक्षित है। –

0

आप एक Mutex या एक मॉनिटर का उपयोग कर कंसोल पर पहुंच सिंक्रनाइज़ चाहिए क्या करना है (lock पर कुछ वस्तु आसान हो जाएगी)।

0

करें कि आपका रंग का एक ताला बयान का उपयोग करके परमाणु लिखते हैं:

// Only one thread can enter this section at a time 
lock(_lockObj) 
{ 
    Console.ForegroundColor = ConsoleColor.Green; 
    Console.WriteLine("\t" + text); 
    Console.ForegroundColor = ConsoleColor.White; 
} 

_lockObj अपने वर्ग के एक निजी स्थिर सदस्य के रूप में घोषित किया जाना चाहिए: आपकी कक्षा एक ही है

private static Object _lockObj = new Object(); 
+0

है यह @pivotnig – adripanico

+0

द्वारा बिल्कुल सुझाव है यह समाधान काम नहीं कर रहा है। मैंने जांच की है कि –

+0

आपके द्वारा प्रदान किए गए कोड से, आपको लॉकिंग को लागू करने के लिए अपनी लिखें विधि की आवश्यकता है, अन्यथा यह रंग को बदलने वाले अन्य दो तरीकों से प्रतिस्पर्धा करेगा: सार्वजनिक स्थैतिक शून्य लिखें (स्ट्रिंग टेक्स्ट) { लॉक (_lockObj) { कंसोल। राइटलाइन (टेक्स्ट); } } – jlew

4

हैं कि कंसोल पर लिख रहा है, फिर एक निजी वस्तु को लॉक कर रहा है, जैसा कि अन्य ने उल्लेख किया है, काम करेगा।

लेकिन यदि अन्य लेखक हैं, तो आपको उनके साथ सिंक्रनाइज़ करने की भी आवश्यकता होगी, अन्यथा वे लॉक के अंदर होने पर लिख सकते हैं। यदि आप Console के कार्यान्वयन को देखते हैं, तो आप देखेंगे कि Console.Out एक SyncTextWriter है, जो स्वयं पर सिंक्रनाइज़ होता है ([MethodImplAttribute(MethodImplOptions.Synchronized)] का उपयोग करके)। इसका मतलब यह है कि अगर आप अपने तुल्यकालन वस्तु के रूप में उपयोग, आप अन्य लेखकों के साथ सिंक्रनाइज़ किया जाएगा:

lock (Console.Out) 
{ 
    Console.ForegroundColor = ConsoleColor.Green; 
    Console.WriteLine("\t" + text); 
    Console.ForegroundColor = ConsoleColor.White; 
} 

यह अभी भी सही ढंग से काम नहीं करेगा अन्य लेखकों भी रंग सेट करते हैं और अपने स्वयं के तुल्यकालन वस्तु का उपयोग करें। लेकिन यह काम करेगा यदि अन्य लेखकों Console.Out पर सिंक्रनाइज़ भी करते हैं।

इस दृष्टिकोण के साथ समस्या यह है कि यह कार्यान्वयन के विवरण पर निर्भर करता है, लेकिन मुझे किसी भी बेहतर समाधान से अवगत नहीं है।

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