سؤال

رمز بلدي:

System.Resources.ResourceManager resourceManager = GetResourceManager();
string str = resourceManager.GetString("delete", new CultureInfo(1033));

في المشروع الحالي تم تجميعه بموجب .NET 2.0 كل شيء يعمل على النحو المستثمر. عامل شارع يحتوي على سلسلة موارد لـ LCID 1033 - حذف, ، لابأس.

نقوم الآن بالترقية إلى .NET 4.0 ، المشروع المعاد ترجمة ضمن الإطار الهدف .NET 4.0. تم تجميعها الآن كجمعيات .NET 4.0 ، وهي ترمي الاستثناء System.ArgumentNullexception مع الرسالة قيمة لا يمكن أن تكون فارغة..تتبع المكدس:

   at System.Threading.Monitor.Enter(Object obj)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)

من المثير للاهتمام هنا StackTrace ، حيث يشير إلى طريقة الإطار الداخلي في ResourceManager.InternalgetResourceset الذي يسبب الاتصال مراقب مع كائن فارغ. لكني أدعو الطريقة getstring مع عدم وجود معلمات فارغة GetString ("Delete" ، New CultureInfo (1033)).

يبدو أن هذا الخطأ مشابه لـ System.ArgumentNullexception in System.Threading.Monitor.enter. ربما بعض الأخطاء في الشاشة. أو أي شيء آخر؟

تحديث: عندما أنظر في مصحح الأخطاء في الكائن resourceManager.ResourceSets.Items[2].Value.Table["delete"] ثم يحتوي على قيمة سلسلة "حذف". عناصر الممتلكات [2] هنا الإشارة إلى LCID 1033. هذا يعني أن مدير الموارد يحتوي بالفعل على سلسلة محلية لمفتاح الموارد حذف في اللغة 1033. هل يعرف أي شخص أين يمكن أن يكون خطأ؟

هل كانت مفيدة؟

المحلول

أعتقد أيضًا أنه يجب عليك إعلان القاموس الخاص بك للتخزين لأن ResourceEts تم تمييزه على أنه قديم بموجب .NET 4.0

نصائح أخرى

لقد وجدت الإجابة بنفسي. فيما يلي تفاصيل: لدينا تنفيذ مخصص لـ ResourceManager مثل هذا:

public class DatabaseResourceManager : System.Resources.ResourceManager 
{
  public DatabaseResourceManager(int applicationID, string bundle) 
  {
    foreach (int languageID in ResourceProvider.Provider.GetLanguages(applicationID))
    {
      DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, languageID);
      ResourceSets.Add(new CultureInfo(languageID), new ResourceSet(r));
    }
}

في .NET 2.0 ، يعمل بشكل جيد ، ولكن في .NET 4.0 ، تغير شيء ما في تنفيذ ResourceManager. this._resourcesets (الذي يستخدم لاحقًا في InternalGetResourceSet للمراقبة. لكن في .NET 4.0 مُنشئ المعلمة لا يقوم بتثبيت مجال خاص this._resourcesets وبالتالي فشلت في وقت لاحق (كما هو موضح أبوب).

يجب أن أعيد كتابة مدير الموارد المخصص الخاص بي لأن هذا للعمل:

public class DatabaseResourceManager : System.Resources.ResourceManager 
{
  public DatabaseResourceManager(int applicationID, string bundle) 
  {
    ResourceSets = new Hashtable();
    this.applicationID = applicationID;
    this.bundle = bundle;
  }

  protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
  {
    if (this.ResourceSets.Contains(culture.Name))
        return this.ResourceSets[culture.Name] as ResourceSet;

    lock (syncLock)
    {
        if (this.ResourceSets.Contains(culture.Name))
            return this.ResourceSets[culture.Name] as ResourceSet;

        DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, culture.LCID);
        ResourceSet rs = new ResourceSet(r);

        this.ResourceSets.Add(culture.Name, rs);

        return rs;
    }
  }
}

"السحر" هنا هو أنه يجب عليّ الكتابة فوق طريقة InternalGetResourceSet لتحميل موارداتي من التخزين المخصص (DB) وإعادة "Resourceset" للثقافة المحددة. الان انها تعمل كالسحر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top