Accéder à la valeur de retour de la fonction déléguée de Thread.Start ()

J’ai un programme qui exécute une méthode à travers un Thread.Start. La méthode a une valeur de retour à laquelle j’aimerais accéder. Y a-t-il un moyen de faire cela? Voici un échantillon …

var someValue = ""; Thread t = new Thread(delegate() { someValue = someObj.methodCall(); }); t.Start(); while (t.isAlive) Thread.Sleep(1000); // Check the value of someValue 

Donc, une fois la boucle while terminée, la someValue devrait être définie – mais comme elle est exécutée dans un autre thread, elle n’est pas définie. Y a-t-il un moyen simple d’y accéder?

Lorsque l’appelant et la méthode threadée partagent une variable, vous y avez déjà access. Une fois le thread terminé, il vous suffit de vérifier someValue .

Bien sûr, vous devez savoir quand la méthode par thread est terminée pour que cela soit utile. En bas, il y a deux façons de faire cela:

  • Envoyez un rappel à la méthode threadée qu’il peut exécuter lorsqu’il est terminé. Vous pouvez transmettre votre méthode de rappel à une someValue . Vous pouvez utiliser cette technique si vous ne vous souciez pas de l’exécution du rappel.

  • Utilisez un WaitHandle de quelque sorte (ou Thread.Join ). Ils vous indiquent quand une ressource est prête ou qu’un événement est terminé. Cette technique est utile si vous souhaitez démarrer un thread, faire autre chose, puis attendre que le thread se termine avant de continuer. (En d’autres termes, c’est utile si vous souhaitez effectuer une synchronisation avec le fil, mais pas tout de suite.)

Je ne peux pas recréer votre problème, j’ai le même code et je vois le résultat attendu. Si vous ne faites que mettre en sumil le fil actuel jusqu’à ce qu’il soit terminé, vous pouvez simplement appeler .Join () sur le fil et attendre pour être sûr que son exécution est terminée.

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } ssortingng someValue = ""; private void Form1_Load(object sender, EventArgs e) { Thread t = new Thread(delegate() { someValue = "asdf"; }); t.Start(); t.Join(); //while (t.IsAlive) Thread.Sleep(1000); System.Diagnostics.Debug.Print(someValue); } } 

L’une des méthodes possibles pour renvoyer une valeur à partir d’un thread consiste à utiliser une classe de contexte en tant qu’object paramètre. Il peut être utilisé pour transmettre des parameters et récupérer le résultat.

Si par contre vous pouvez utiliser une classe BackgroundWorker, elle a déjà un object Result dédié – qui fonctionne de la même manière. Mais BackgroundWorker ne peut pas être utilisé à certaines fins (par exemple, il ne prend pas en charge STA Apartment State).

N’oubliez pas que vous ne devez pas lire ctx.Result avant la fin du thread (ietIsAlive == false).

  void runThread() { ThreadContext ctx = new ThreadContext(); ctx.Value = 8; Thread t = new Thread(new ParameterizedThreadStart(MyThread)); //t.SetApartmentState(ApartmentState.STA); // required for some purposes t.Start(ctx); // ... t.Join(); Console.WriteLine(ctx.Result); } private static void MyThread(object threadParam) { ThreadContext context = (ThreadContext)threadParam; context.Result = context.Value * 4; // compute result } class ThreadContext { public int Value { get; set; } public int Result { get; set; } } 

Vous pouvez récupérer des données à partir de la fonction Thread en utilisant le rappel de délégué. Le délégué peut servir de pont entre le thread et l’appelant. Par exemple:

 public delegate void DelReturnValue(ssortingng value); public class SayHello { private ssortingng _name; private DelReturnValue _delReturnValue; public SayHello(ssortingng name, DelReturnValue delReturnValue) { _name = name; _delReturnValue = delReturnValue; } public void SayHelloMethod() { _delReturnValue(_name); } } public class Caller { private static ssortingng _returnedValue; public static void ReturnValue(ssortingng value) { _returnedValue = value; } public static void Main() { DelReturnValue delReturnValue=new DelReturnValue(ReturnValue); SayHello sayHello = new SayHello("test", delReturnValue); Thread newThread = new Thread(new ThreadStart(sayHello.SayHelloMethod)); newThread.Start(); Thread.Sleep(1000); Console.WriteLine("value is returned: " + _returnedValue); } } 

Regardez le modèle de programmation asynchrone .

Dans l’un des modèles courants décrits par le modèle, votre classe exposera les méthodes BeginXXX et EndXXX. Le premier démarre l’opération asynchrone et retourne un object IAsyncResult. Ce dernier accepte l’object IAsyncResult en tant qu’argument, bloque le thread appelant jusqu’à la fin de l’opération et renvoie la valeur requirejse.