318 votes

Comment passer des paramètres à la méthode ThreadStart dans un Thread ?

Comment passer des paramètres à Thread.ThreadStart() en C# ?

Supposons que j'ai une méthode appelée "download".

public void download(string filename)
{
    // download code
}

Maintenant j'ai créé un thread dans la méthode main :

Thread thread = new Thread(new ThreadStart(download(filename));

erreur type de méthode attendue.

Comment puis-je passer des paramètres à ThreadStart avec une méthode cible avec des paramètres ?

3 votes

Vérifiez ce article écrit par Jon Skeet La section sur les paramètres se trouve à la page suivante, mais l'article dans son ensemble est plutôt intéressant à lire.

4voto

Je vous recommanderais d'avoir une autre classe appelée Dossier.

public class File
{
   private string filename;

   public File(string filename)
   {
      this.filename= filename;
   }

   public void download()
   {
       // download code using filename
   }
}

Et dans votre code de création de fil, vous instanciez un nouveau fichier :

string filename = "my_file_name";

myFile = new File(filename);

ThreadStart threadDelegate = new ThreadStart(myFile.download);

Thread newThread = new Thread(threadDelegate);

3voto

Jackypengyu Points 36

Vous pouvez encapsuler la fonction thread (téléchargement) et le(s) paramètre(s) nécessaire(s) (nom du fichier) dans une classe et utiliser le délégué ThreadStart pour exécuter la fonction thread.

public class Download
{
    string _filename;

    Download(string filename)
    {
       _filename = filename;
    }

    public void download(string filename)
    {
       //download code
    }
}

Download = new Download(filename);
Thread thread = new Thread(new ThreadStart(Download.download);

0voto

Que pensez-vous de ceci : (ou est-ce que je peux l'utiliser comme ça ?)

var test = "Hello";
new Thread(new ThreadStart(() =>
{
    try
    {
        //Staff to do
        Console.WriteLine(test);
    }
    catch (Exception ex)
    {
        throw;
    }
})).Start();

-1voto

Markus Safar Points 3120

Selon votre question...

Comment passer des paramètres à la méthode Thread.ThreadStart() en C# ?

...et l'erreur que vous avez rencontrée, vous devriez corriger votre code à partir de

Thread thread = new Thread(new ThreadStart(download(filename));

à

Thread thread = new Thread(new ThreadStart(download));
thread.Start(filename);

Cependant, la question est plus complexe qu'il n'y paraît au premier abord.

En Thread Actuellement, la classe (4.7.2) fournit plusieurs fonctions de constructeurs et un Start avec des surcharges.

Ces constructeurs pertinents pour cette question sont :

public Thread(ThreadStart start);

y

public Thread(ParameterizedThreadStart start);

qui prennent soit un ThreadStart ou un délégué ParameterizedThreadStart délégué.

Les délégués correspondants ressemblent à ceci :

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);

Ainsi, comme on peut le voir, le constructeur correct à utiliser semble être celui qui prend une valeur de ParameterizedThreadStart afin qu'une méthode conforme à la signature spécifiée du délégué puisse être lancée par le thread.

Un exemple simple d'instanciation de la Thread La classe serait

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

ou simplement

Thread thread = new Thread(Work);

La signature de la méthode correspondante (appelée Work dans cet exemple) ressemble à ceci :

private void Work(object data)
{
   ...
}

Il ne reste plus qu'à lancer le fil. Cela se fait en utilisant soit

public void Start();

ou

public void Start(object parameter);

Alors que Start() commencerait le fil et passerait null comme données pour la méthode, Start(...) peut être utilisé pour passer tout ce qui est dans le Work du fil.

Il y a cependant un gros problème avec cette approche : Tout ce qui est passé dans le Work est transformée en objet. Cela signifie qu'au sein de la méthode Work il doit être remis dans le type original comme dans l'exemple suivant :

public static void Main(string[] args)
{
    Thread thread = new Thread(Work);

    thread.Start("I've got some text");
    Console.ReadLine();
}

private static void Work(object data)
{
    string message = (string)data; // Wow, this is ugly

    Console.WriteLine($"I, the thread write: {message}");
}

Le moulage est une chose que vous ne voulez généralement pas faire.

Que se passe-t-il si quelqu'un passe quelque chose d'autre qui n'est pas une chaîne ? Comme cela ne semble pas possible au départ (parce que C'est ma méthode, je sais ce que je fais. o La méthode est privée, comment quelqu'un pourrait-il lui passer quelque chose ? ), vous pouvez éventuellement vous retrouver dans ce cas précis pour diverses raisons. Si certains cas ne posent pas de problème, d'autres en posent. Dans ces cas-là, vous vous retrouverez probablement avec un fichier InvalidCastException que vous ne remarquerez probablement pas, car il met simplement fin au fil.

En guise de solution, on s'attendrait à obtenir un générique ParameterizedThreadStart délégué comme ParameterizedThreadStart<T> donde T serait le type de données que vous voulez passer dans la fonction Work méthode. Malheureusement, une telle méthode n'existe pas (encore ?).

Il existe cependant un solution proposée à cette question. Il s'agit de créer une classe qui contient à la fois les données à transmettre au thread et la méthode qui représente la méthode du travailleur, comme ceci :

public class ThreadWithState
{
    private string message;

    public ThreadWithState(string message)
    {
        this.message = message;
    }

    public void Work()
    {
        Console.WriteLine($"I, the thread write: {this.message}");
    }
}

Avec cette approche, vous commencerez le fil de discussion comme ceci :

ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);

thread.Start();

De cette façon, vous évitez simplement le casting et disposez d'un moyen sûr de fournir des données à un thread ;-)

-2voto

Aylian Craspa Points 21

Voici le moyen parfait...

private void func_trd(String sender)
{

    try
    {
        imgh.LoadImages_R_Randomiz(this, "01", groupBox, randomizerB.Value); // normal code

        ThreadStart ts = delegate
        {
            ExecuteInForeground(sender);
        };

        Thread nt = new Thread(ts);
        nt.IsBackground = true;

        nt.Start();

    }
    catch (Exception)
    {

    }
}

private void ExecuteInForeground(string name)
{
     //whatever ur function
    MessageBox.Show(name);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X