الوصول إلى نفس السلسلة (StringBuilder) باستخدام مؤشر ترابط متعدد

StackOverflow https://stackoverflow.com/questions/1268446

  •  13-09-2019
  •  | 
  •  

سؤال

مشكلتي إذا كنت تستخدم موضوع متعدد على نفس السلسلة في وقت ما

السلسلة لن تحل محل. (كتبت هذا على المفكرة حتى يكون بناء الجملة

خاطئ - ظلم - يظلم)

باستخدام System.Thread ... آخر فكورسي

class ....
{
    private static StringBuild container = new StringBuilder();

    static void Main(...)
    {
    container.Append(Read From File(Kind of long));
    Thread thread1 = new Thread(Function1);
        Thread thread2 = new Thread(Function2);
    thread1.Start();
    thread2.Start();
    //Print out container
    }

    static void Function1
    {
    //Do calculation and stuff to get the Array for the foreach
    foreach (.......Long loop........)
    {
    container.Replace("this", "With this")
    }
    }
    //Same goes for function but replacing different things.
    static void Function2
    {
    //Do calculation and stuff to get the Array for the foreach
    foreach (.......Long loop........)
    {
    container.Replace("this", "With this")
    }
    }
}

الآن في وقت ما بعض العناصر لا يحصل على استبدال. لذلك حلاي لهذا هو استدعاء الحاوية. مكان مختلف

الطريقة والقيام "قفل" الذي يعمل ولكنه هو الطريق الصحيح؟

private class ModiflyString
{
        public void Do(string x, string y)
            {
                lock (this)
                {
                    fileInput.Replace(x, y);
                }
            }
}
هل كانت مفيدة؟

المحلول

يجب عليك قفل كائن StringBuilder نفسه (داخل وظائف استبدال):

lock (container)
{
   container.Replace("this", "With this");
}

أو إنشاء كائن قفل منفصل:

static object _stringLock = new object();

...

lock(stringLock)
{
    container.Replace("this", "With this");
}

نصائح أخرى

لن يعمل Locking الخاص بك عند إنشاء كائن أكثر من 1 أكثر من 1 كائن ModifyString وأنا أظن أنك تقوم بذلك.

نسخة بسيطة:

   public void Do(string x, string y)
   {
      lock (fileInput)
      {
         fileInput.Replace(x, y);
      }
   }

قد يكون من الأفضل إنشاء كائن منفصل للقيام بالقفل، لكن ما ورد أعلاه يوضح المبدأ أفضل: يجب أن قفل جميع المواضيع المتنافسة على نفس الكائن.

سوف يبدو النهج القياسي:

private static StringBuild container = new StringBuilder();
private static object syncLock = new object();  // simple object, 1-1 with container

ثم يمكنك (الخيط) استخدام بأمان:

   lock(syncLock)
   {
       container.Replace(...);
   }

سيعمل ذلك على ما يرام طالما أن كل من الخيوط لها نفس مثيل فئة ModifyString. بمعنى آخر، سيعمل هذا لأن القفل على "هذا" يجب أن يكون قفل في نفس المثيل:

class Blah
{
    private static StringBuild container = new StringBuilder();

    private static ModifyString modifyString = new ModifyString();

    static void Main(...)
    {
    container.Append(Read From File(Kind of long));
    Thread thread1 = new Thread(Function1);
        Thread thread2 = new Thread(Function2);
    thread1.Start();
    thread2.Start();
    //Print out container
    }

    static void Function1
    {       

        //Do calculation and stuff to get the Array for the foreach
        foreach (.......Long loop........)
        {
           modifyString.Do("this", "With this")
       }
    }
    //Same goes for function but replacing different things.
    static void Function2
    {
        //Do calculation and stuff to get the Array for the foreach
        foreach (.......Long loop........)
        {
            modifyString.Do("this", "With this")
        }
    }
}

سوف تكون ليس العمل إذا فعلت أدناه، لأن القفل (هذا) لن ينشئ أنهم حالات منفصلة:

class Blah
{
    private static StringBuild container = new StringBuilder();

    static void Main(...)
    {
    container.Append(Read From File(Kind of long));
    Thread thread1 = new Thread(Function1);
        Thread thread2 = new Thread(Function2);
    thread1.Start();
    thread2.Start();
    //Print out container
    }

    static void Function1
    {
       ModifyString modifyString = new ModifyString();
       //Do calculation and stuff to get the Array for the foreach
       foreach (.......Long loop........)
       {
          modifyString.Do("this", "With this")
       }
    }
    //Same goes for function but replacing different things.
    static void Function2
    {
       ModifyString modifyString = new ModifyString();

       //Do calculation and stuff to get the Array for the foreach
        foreach (.......Long loop........)
        {
            modifyString.Do("this", "With this")
        }
    }
}

سيقوم بعض الأشخاص بإنشاء كائن "وهمية" في الواقع لأداء القفل بدلا من استخدام "هذا" (لا يمكنك قفل على السلسلة لأنه نوع قيمة).

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