6

.net में उपयोगकर्ता प्रोफ़ाइल-संस्कृति के अलावा किसी अन्य संस्कृति को एक संपूर्ण .net एप्लिकेशन सेट करना संभव नहीं है। Cultureinfo को नियंत्रित करने का उचित तरीका डेटटाइम जैसी वस्तुओं पर समर्पित विधियों का उपयोग करना प्रतीत होता है।थ्रेडिंग, CultureInfo .net, TPL, PLINQ

हालांकि, विरासत कोड की बड़ी मात्रा (आपके नियंत्रण में सभी कोड नहीं) से निपटने पर यह हासिल करना संभव नहीं है। इसके लिए उदाहरण के लिए थ्रेड ओच थ्रेडपूल में सबक्लास/रैपर बना सकते हैं और प्रतिनिधि को निष्पादित करने से पहले आवश्यक संस्कृतिइन्फो सेट कर सकते हैं, या प्रतिनिधि को स्वयं संस्कृति का एक सेट होना आवश्यक हो सकता है। (मान्य करने के लिए कठोर और गलत तरीके से प्रवण ...)

टीपीएल को देखते हुए, विशेष रूप से PLINQ, हालांकि मुझे असंभव नहीं है, अगर असंभव नहीं है, तो केंद्रीकृत तरीके से संस्कृति सेटिंग्स को बदलने के लिए।

कोई भी सुझाव जो लीगेसी कोड में थ्रेड/एप्लिकेशन-संस्कृतिइन्फो को ओवरराइड करने से संबंधित है?

धन्यवाद!

उत्तर

6

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

मैंने एक एक्सटेंशन लिखा था। कि के लिए:

public static class ParallelQueryCultureExtensions 
{ 
    public static ParallelQuery<TSource> SetCulture<TSource>(this ParallelQuery<TSource> source, CultureInfo cultureInfo) 
    { 
     SetCulture(cultureInfo); 
     return source 
      .Select(
       item => 
        { 
         SetCulture(cultureInfo); 
         return item; 
        }); 
    } 

    private static void SetCulture(CultureInfo cultureInfo) { 
     if (Thread.CurrentThread.CurrentCulture != cultureInfo) { 
      Thread.CurrentThread.CurrentCulture = cultureInfo; 
     } 
    } 
} 

तो अगर आप यह सिर्फ .AsParallel का उपयोग कर मूल स्रोत ऊपर बंटवारे के बाद() का उपयोग आप आप क्या चाहते हैं मिल जाएगा।

CultureInfo kaCulture = CultureInfo.GetCultureInfo("ka-Ge"); 

    int[] array = new int[100]; 
    Random random = new Random(); 
    int index =0; 
    Array.ForEach(array, i => { array[index++] = index;}); 

    array 
     .AsParallel() 
     .SetCulture(kaCulture) 
     .ForAll(
      i => 
       { 
        Thread.Sleep(random.Next(5)); 
        Console.WriteLine("Thread-{0} \t Culture-'{1}' \t Element-{2}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.CurrentCulture, i); 
       }); 

    Console.WriteLine("Press any key to quit"); 
    Console.ReadKey(); 
+1

यह कम से कम काम करता है, कम से कम जब तक मैं .NET 4.5 पर जा सकता हूं :) – Porco

1

आश्चर्यजनक रूप से इस एक्सटेंशन ने मेरे PLINQ प्रश्नों को धीमा नहीं किया - जिसे मैं माप सकता था।

कई AsParallel() कॉल के साथ एक जटिल क्वेरी में, आपको प्रत्येक AsParallel() के बाद SetCulture() को कॉल करना पड़ सकता है। मुझे यकीन नहीं है कि क्या एक स्थान जोड़ने के लिए है .सेटकल्चर() (या उस मामले के लिए AsParallel के लिए एक स्थान), इसलिए मैंने बस जोड़ा है। प्रत्येक AsParallel() कॉल के बाद .etCulture(), और यह बहुत अच्छा काम किया।

इसके अतिरिक्त आप CurrentUICulture को भी सेट करने पर विचार कर सकते हैं। उदा। टूटा नियमों (सीएसएलए ढांचे, टूटे हुए नियम संग्रह) के साथ व्यापार ऑब्जेक्ट्स खोजने के लिए व्यवसाय ऑब्जेक्ट संग्रह खोजने के लिए PLINQ का उपयोग करना त्रुटि स्ट्रिंग सेट करने के लिए स्थानीय (हमारी आवश्यकता) स्ट्रिंग संसाधनों को देखने के लिए PLINQ थ्रेड्स (थ्रेड पूल थ्रेड्स) का कारण बनता है (RuleArgs। विवरण)।

मुझे केवल समानांतरक्चरकल्चर एक्सटेंशन एक्सटेंशन का विस्तार करने की आवश्यकता है। यह मेरे लिए अच्छी तरह से काम (मैं VB.NET उपयोग करने के लिए है, इसलिए ...):

Public Module PLINQExtensions 

    <Extension()> _ 
    Public Function SetCulture(Of TSource)(ByVal source As ParallelQuery(Of TSource), ByVal culture As CultureInfo, ByVal uiCulture As CultureInfo) As ParallelQuery(Of TSource) 
     SetCulture(culture, uiCulture) 
     Return source.Select(Function(item) 
           SetCulture(culture, uiCulture) 
           Return item 
          End Function 
          ) 
    End Function 

    <Extension()> _ 
    Private Sub SetCulture(ByVal culture As CultureInfo, ByVal uiCulture As CultureInfo) 
     If (Not Thread.CurrentThread.CurrentCulture.Equals(culture)) Then 
      Thread.CurrentThread.CurrentCulture = culture 
     End If 

     If (Not Thread.CurrentThread.CurrentUICulture.Equals(uiCulture)) Then 
      Thread.CurrentThread.CurrentUICulture = uiCulture 
     End If 
    End Sub 

End Module 
2

.NET 4.5 के साथ शुरू आप (देखें एक पूरे AppDomain के लिए संस्कृति को परिभाषित करने में सक्षम हो जाएगा पैरा शीर्षक "कोर नई विशेषताएं और सुधार ")।

0

जब मैं टीपीएल का उपयोग करके एक कार्य बनाता हूं, तो मैं एक स्टेट ऑब्जेक्ट का उपयोग करके पृष्ठभूमि थ्रेड पर वर्तमान यूआई-थ्रेड से संस्कृति को पास करता हूं।

private void WorkProcessingAsync(IWorkItem workItem) 
     { 
      IsBusy = true; 
      /* ============================= 
      * Create a TPL Task and pass the current UiCulture in an state Object to resolve the correct .resx file for translation/globalisation/Multila`enter code here`nguate features in Background Thread 
      * ==============================*/ 
      Task<IWorkItem> task = Task.Factory.StartNew((stateObj) => 
      { 
       // here we are already in the task background thread 
       // save cast the given stateObj 
       var tuple = stateObj as Tuple<IWorkItem, CultureInfo>; 


      Debug.Assert(tuple != null, "tuple != null"); 

      Thread.CurrentThread.CurrentUICulture = tuple.Item2; // Here we set the UI-Thread Culture to the Background Thread 

      var longRunningOperationAnswer = LongRunningOperation.DoLongWork(tuple.Item1); 
      return longRunningOperationAnswer; 

     }, new Tuple<IWorkItem, CultureInfo>(workItem, Thread.CurrentThread.CurrentUICulture)); // here we pass the UI-Thread Culture to the State Object 



     /* ======================================================================= 
     * Handle OnlyOnRanToCompletion Task and process longRunningOperationAnswer back in UiThread 
     * =======================================================================*/ 
     task.ContinueWith((t) => 
     { 
      IsBusy = false; 
      // handle longRunningOperationAnswer here in t.Result 
      Log.Debug("Operation completet with {0}", t.Result); 

     }, CancellationToken.None 
     , TaskContinuationOptions.OnlyOnRanToCompletion 
     , TaskScheduler.FromCurrentSynchronizationContext()); 

     /* ======================================================================= 
    * Handle OnlyOnFaulted Task back in UiThread 
    * =======================================================================*/ 
     task.ContinueWith((t) => 
     { 
      IsBusy = false; 
      AggregateException aggEx = t.Exception; 

      if (aggEx != null) 
      { 
       aggEx.Flatten(); 
       Log.ErrorFormat("The Task exited with Exception(s) \n{0}", aggEx); 
       foreach (Exception ex in aggEx.InnerExceptions) 
       { 
        if (ex is SpecialExaption) 
        { 
         //Handle Ex here 
         return; 
        } 
        if (ex is CustomExeption) 
        { 
         //Handle Ex here 
         return; 
        } 
       } 
      } 
     }, CancellationToken.None 
     , TaskContinuationOptions.OnlyOnFaulted 
     , TaskScheduler.FromCurrentSynchronizationContext()); 
    } 
संबंधित मुद्दे