Pregunta

Mi problema es si uso multi-hilo en la misma cadena en algún momento

la cadena no conseguirá sustituir. (Escribí este modo en la libreta de sintaxis puede ser

mal)

usando System.Thread ... Otros 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")
    }
    }
}

Ahora en algún momento algún elemento no consigue sustituir. Así que mi solución a este container.Replace está llamando en una diferente

método y no un "bloqueo", que es trabajo, pero de la manera correcta?

private class ModiflyString
{
        public void Do(string x, string y)
            {
                lock (this)
                {
                    fileInput.Replace(x, y);
                }
            }
}
¿Fue útil?

Solución

Se debe bloquear el propio objeto StringBuilder (dentro de las funciones de reemplazar):

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

o crear un objeto de bloqueo separado:

static object _stringLock = new object();

...

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

Otros consejos

Su bloqueo no funcionará cuando se crea más de 1 objeto ModifyString y supongo que haces.

Una versión simple:

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

Puede que sea mejor para crear un objeto independiente para hacer el bloqueo, pero el anterior muestra el principio mejor:. Todas las discusiones que compiten deben bloquear en el mismo objeto

Un enfoque estándar se vería así:

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

y luego se puede (thread-) de manera segura de usar:

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

Eso funcionará bien siempre y cuando ambos hilos tienen la misma instancia de la clase ModifyString. En otras palabras, esto funciona porque la cerradura de "este" debe ser un bloqueo en la misma instancia:

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")
        }
    }
}

no de trabajo si se hizo el siguiente, porque el bloqueo (esto) no funcionaría sentido, son dos casos separados:

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")
        }
    }
}

Algunas personas realmente crear un objeto "de prueba" para llevar a cabo el bloqueo en lugar de utilizar "este" (no se puede bloquear en la cuerda, ya que es un tipo de valor).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top