简体   繁体   中英

Is this code thread safe? C#

A lot of code have been deleted, but I really need to show only this part. The main idea: method Localize() must work speedy, so it mustn't be locked by any other thread. It uses flag isLoaded to detect, which type of localization to use - Old or Current.

static class Localization
{
    static readonly object locker = new object();

    static string LocalizationDir;

    static bool isLoaded;
    static Tuple<string, string> OldLanguage;
    static Dictionary<string, string> OldLocalization;
    static Dictionary<string, string> CurrentLocalization;

    public static Tuple<string, string> CurrentLanguage {
        get;
        private set;
    }

    static Localization() {
        lock ( locker ) {
            OldLanguage = null;
            CurrentLanguage = new Tuple<string, string>("en", "English");
            isLoaded = true;

            OldLocalization = null;
            CurrentLocalization = null;
        }
    }

    public static bool SetLanguage(string languageShortName) {
        lock ( locker ) {
            string languagePath = Path.Combine(LocalizationDir, languageShortName + ".loc");

            // save localization, be ready to return it back
            OldLocalization = CurrentLocalization;
            OldLanguage = CurrentLanguage;
            isLoaded = false;

            try {
                using ( TextReader i = new StreamReader(languagePath) ) {
                    /*
                        Parse file, 
                        Modify CurrentLocalization, CurrentLocalization
                    */
                }
            }
            catch ( Exception e ) {
                // Just return back our good localization data

                CurrentLocalization = OldLocalization;
                CurrentLanguage = OldLanguage;
                isLoaded = true;

                OldLocalization = null;
                OldLanguage = null;

                return false;
            }

            // everything is good
            {
                OldLocalization = null;
                OldLanguage = null;
                isLoaded = true;

                UpdateControls();
            }

            return true;
        }
    }


    // <summary>
    // We think that there are no bugs in this method
    // No locking
    // </summary>
    public static string Localize(this string Text) {
        if ( CurrentLanguage.Item2 == "English" )
            return Text;

        Dictionary<string, string> ChoosedLocalization = null;
        if ( !isLoaded && OldLocalization != null )
            ChoosedLocalization = OldLocalization;
        else if ( isLoaded && CurrentLocalization != null )
            ChoosedLocalization = CurrentLocalization;

        if ( ChoosedLocalization != null ) {
            string Translate;

            if ( !ChoosedLocalization.TryGetValue(Text, out Translate) )
                return Text;
            else
                return Translate;
        }
        else
            return Text;
    }
} 

I suspect it is not. I also suspect that you're overthinking things. In SetLanguage, all you should do it load up the new dictionary and then swap it in for the old. That assignment is atomic, so as long as your Translate code doesn't use CurrentLanguage twice in a row and assume it'll be the same and that UpdateControls call waits until a previous call is done (or some other race condition prevention) then it should be simpler, cleaner, and more reliable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM