web-dev-qa-db-fra.com

Passer des paramètres via ParameterizedThreadStart

J'essaie de passer des paramètres à travers ce qui suit:

Thread thread = new Thread(new ParameterizedThreadStart(DoMethod));

Une idée comment faire ça? J'apprécierais un peu d'aide

42
liamp47

lazyberezovsky a la bonne réponse. Je tiens à noter que techniquement, vous pouvez transmettre un nombre arbitraire d'arguments à l'aide de l'expression lambda en raison de la capture de variables:

var thread = new Thread(
       () => DoMethod(a, b, c));
thread.Start();

C'est un moyen pratique d'appeler des méthodes qui ne correspondent pas au délégué ThreadStart ou ParameterizedThreadStart, mais veillez à ce que vous puissiez facilement provoquer une course de données si vous modifiez les arguments dans le thread parent après les avoir passés au code du thread enfant.

86
Tudor

Utilisez overloaded Thread.Start method, qui accepte un objet (vous pouvez transmettre votre type ou votre tableau personnalisé si vous avez besoin de plusieurs paramètres):

Foo parameter = // get parameter value
Thread thread = new Thread(new ParameterizedThreadStart(DoMethod));
thread.Start(parameter);

Et dans DoMethod, transtypez simplement l'argument en votre type de paramètre:

private void DoMethod(object obj)
{
    Foo parameter = (Foo)obj;
    // ...    
}

BTW dans .NET 4.0 et versions ultérieures, vous pouvez utiliser des tâches (soyez également prudent avec les conditions de concurrence):

Task.Factory.StartNew(() => DoMethod(a, b, c));
32
Sergey Berezovskiy

Un autre moyen d'archiver ce que vous voulez consiste à renvoyer un délégué dans votre fonction/méthode. Prenons l'exemple suivant:

class App
{
  public static void Main()
  {
     Thread t = new Thread(DoWork(a, b));
     t.Start();
     if (t.IsAlive)
     {
         t.IsBackground = true;
     }
  }

  private static ThreadStart DoWork(int a, int b)
  {
      return () => { /*DoWork*/ var c = a + b; };
  }

}
1
Lorenz Lo Sauer
new Thread(() => { DoMethod(a, b, c); }).Start();

ou

new Thread(() => DoMethod(a, b, c)).Start();
1
Fly Rose

Au lieu de créer une classe pour transmettre plusieurs paramètres, comme @ user1958681 l'a fait, vous pouvez utiliser des types anonymes, puis utilisez simplement la frappe dynamique pour extraire vos paramètres.

class MainClass
{
    int A = 1;
    string B = "Test";

    Thread ActionThread = new Thread(new ParameterizedThreadStart(DoWork));    
    ActionThread.Start(new { A, B});
}

Puis dans DoWork

private static void DoWork(object parameters)
{
   dynamic d = parameters;

    int a = parameters.A;
    string b = parameters.B;
 }
0
Peter Henry
// Parameters to pass to ParameterizedThreadStart delegate
// - in this example, it's an Int32 and a String:
class MyParams
{
    public int A { get; set; }
    public string B { get; set; }

    // Constructor
    public MyParams(int someInt, string someString)
    {
        A = someInt;
        B = someString;
    }
}

class MainClass
{
    MyParams ap = new MyParams(10, "Hello!");
    Thread t = new Thread(new ParameterizedThreadStart(DoMethod));
    t.Start(ap); // Pass parameters when starting the thread
}
0
user1958681