ResourceManager a wielowątkowość w WebAPI

0

Cześć,
Czy ResourceManager jest odporny na wielowątkowe pobieranie tekstów?
Mam taką klasę:

public class ResourcesRepository
{
    private static System.Resources.ResourceManager _resourceManager = null;

    public static string GetResourceText(string key, CultureInfo culture)
    {
        if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(nameof(key)); }
        if (culture == null) { throw new ArgumentNullException(nameof(culture)); }

        if (_resourceManager == null)
        {
            _resourceManager = new System.Resources.ResourceManager(typeof(ResourcesText));
        }

        return _resourceManager.GetString(key, culture);
    }
}

Zastanawiam się teraz jak mam kilka endpointów w webapi, które działają asynchroniczne i wewnątrz wywołują inne metody asynchroniczne, a ResourceText pobieram za pomocą statycznej metody GetResourceText(key, cultureInfo), to czy nie wysypie mi się to w momencie jeśli _resourceManager.GetString(key, culture) zostanie w tym samym momencie wywołany przez kilka wątków?
Może tworzenie instancji _resourceManager i samo GetString lepiej jeszcze opakować w lock(){ } ?

Zastanawiałem się jeszcze czy nie zrobić tej klasy jako singleton, instancje _resourceManager tworzyć przy odpalaniu api i zrobić go jako readonly.
Macie może jeszcze jakieś ciekawe propozycje?

0

Odnośnie dostępu wielowątkowego:

https://docs.microsoft.com/en-us/dotnet/api/system.resources.resourcemanager?view=netframework-4.8#thread-safety

This type is thread safe.

Odnośnie tworzenia (usunąłem komentarz bo nie zauważyłem, że masz to w staticu):
https://docs.microsoft.com/en-us/dotnet/api/system.lazy-1?view=net-6.0

0

A to źle, że jest w static? dotychczas tak tego używałem, ale zacząłem się martwić że może to być niebezpieczne dla wielowątkowości. Mam to w static żeby nie wstrzykiwać tego do każdego kontrolera. Chyba nie do końca rozumiem jak działa to Lazy i do czego służy i jakie to ma zastosowanie do mojego problemu. Skoro ResourceManager jest thread safe to nie powinno być problemu?

1

@blane:

A to źle, że jest w static?

To zależy, ale na pewno będzie Ci trudniej taki kod przetestować. Jeżeli byłby to wstrzykiwany singleton to nie byłoby tego problemu. Kod będzie luźniej połączony a to oznacza, że masz większe możliwości zmian bez angażowania innych miejsc w kodzie. Osobiście unikam publicznych funkcji statyczynych.

Chyba nie do końca rozumiem jak działa to Lazy i do czego służy i jakie to ma zastosowanie do mojego problemu. Skoro ResourceManager jest thread safe to nie powinno być problemu?

To, że resource manager jest bezpieczny nie znaczy, że tworzenie go w publicznej statycznej jest bezpieczne. Aktualne ta metoda ma możliwość odpalenia się równolegle i stworzenia obiektu dwukrotnie (w tym przypadku to jest tylko odczyt z klaski, więc żadnych danych się nie traci, ale w sumie nie wiem czy nie wybuchnie).

Możesz taką zmienną inicjalizować w statycznym konstruktorze albo skorzystać z Lazy.

public sealed class Singleton
{
    // Because Singleton's constructor is private, we must explicitly
    // give the Lazy<Singleton> a delegate for creating the Singleton.
    static readonly Lazy<Singleton> instanceHolder =
        new Lazy<Singleton>(() => new Singleton());

    Singleton()
    {
        // Explicit private constructor to prevent default public constructor.
        ...
    }

    public static Singleton Instance => instanceHolder.Value;
}

https://stackoverflow.com/questions/6847721/when-should-i-use-lazyt

0

Ja w pytaniu widzę słowny kalambur(???) , problem z ideą zagadnienia.

Zasób / resource w tradycyjnym powszechnym rozumieniu w informatyce to jest coś niezmienne, dane stałe, które są pobierane przez kod.

Jako takie nie ma tam zbytnio zagrożeń od-wątkowych czy podobnych ...

Więc może
a) nie myśleć o tym jako o Resouce a nazwac inaczej - jeśli musi to być coś dynamicznego
b) przeanalizować pod kątem niezmienników, jeśli to są prawdziwe Zasoby

1 użytkowników online, w tym zalogowanych: 0, gości: 1