الوصول إلى نفس السلسلة (StringBuilder) باستخدام مؤشر ترابط متعدد
-
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")
}
}
}
سيقوم بعض الأشخاص بإنشاء كائن "وهمية" في الواقع لأداء القفل بدلا من استخدام "هذا" (لا يمكنك قفل على السلسلة لأنه نوع قيمة).