Accès à la même chaîne (StringBuilder) en utilisant des multi-thread
-
13-09-2019 - |
Question
Mon problème est de savoir si j'utilise multi-thread sur la même chaîne un jour
la chaîne ne sera pas remplacer. (Je l'ai écrit ceci sur le bloc-notes si la syntaxe peut être
mauvais)
à l'aide System.Thread ... D'autres ofcourse
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")
}
}
}
Maintenant, quelque temps un élément ne soit pas remplacer. Donc, ma solution à ce appelle container.Replace sur un autre
méthode et faire un « verrouillage » qui fonctionnent mais est-ce la bonne façon?
private class ModiflyString
{
public void Do(string x, string y)
{
lock (this)
{
fileInput.Replace(x, y);
}
}
}
La solution
Vous devez verrouiller l'objet StringBuilder lui-même (à l'intérieur des fonctions remplacer):
lock (container)
{
container.Replace("this", "With this");
}
ou de créer un objet de verrouillage séparé:
static object _stringLock = new object();
...
lock(stringLock)
{
container.Replace("this", "With this");
}
Autres conseils
Votre verrouillage ne fonctionne pas lorsque vous créez plus de 1 objet ModifyString et je devine que vous faites.
Une version simple:
public void Do(string x, string y)
{
lock (fileInput)
{
fileInput.Replace(x, y);
}
}
Il peut être préférable de créer un objet distinct pour faire le verrouillage, mais le montre au-dessus du principe mieux:. Toutes les discussions concurrentes doivent se verrouiller sur le même objet
Une approche standard ressemblerait à ceci:
private static StringBuild container = new StringBuilder();
private static object syncLock = new object(); // simple object, 1-1 with container
et vous pouvez (thread-) utiliser en toute sécurité:
lock(syncLock)
{
container.Replace(...);
}
Cela fonctionne bien aussi longtemps que les deux fils ont la même instance de la classe ModifyString. En d'autres termes, cela fonctionne parce que le verrou sur « ce » doit être un verrou sur la même instance:
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")
}
}
}
Il sera pas travail si vous avez fait le ci-dessous, parce que verrou (cela) ne fonctionnerait pas sens, ils sont deux cas distincts:
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")
}
}
}
Certaines personnes effectivement créer un objet « factice » pour effectuer la serrure au lieu d'utiliser « ce » (vous ne pouvez pas verrouiller sur la corde, car il est un type de valeur).