8
votes

Comment mettre fin à un thread géré bloqué dans le code non géré?

J'ai un fil géré qui attend, bloqué, dans un code non géré (précisément, sur un appel à NamedPiPeserverStream.waitforconnection () qui appelle ultime à un code non géré et fait pas offre un délai d'attente).

Je veux fermer le fil de côté.

thread.Abort () n'a aucun effet tant que le code ne renvoie pas au domaine géré, ce qu'il ne fera pas jusqu'à ce que un client ne soit une connexion, que nous ne pouvions pas attendre).

J'ai besoin d'une manière "choc" hors du code non géré; ou un moyen de tuer le fil même alors que c'est dans des terres non gérées.


3 commentaires

Toute raison pour laquelle vous n'utilisez pas NamedPipeserverstream.beginwaitForConnection () à la place?


Fondamentalement, parce que le fil veut attendre "pour toujours" pour une connexion (sauf si arrêt). Avec Begin / End WaitForConnection, je devrais commencer, attendre une seconde, vérifier la connexion ou le délai d'attente et la boucle sur le délai d'attente.


Ok je comprends ça. Une légère modification de la réponse de DTB devrait vous donner ce dont vous avez besoin. Au lieu d'attendre l'asyncrezulte, attendez un waihandle partagé que vous avez défini du code qui susceptibles d'abandonner le fil.


3 Réponses :


20
votes

Avez-vous essayé d'utiliser le non-blocage namedpipeserverStream.beginwaitforconnection méthode? XXX PRE>

Vous n'avez pas nécessairement besoin d'utiliser un délai fixe. Vous pouvez utiliser un ManualResetEvent pour signaler quand le fil devrait Arrêtez d'attendre la connexion: P>

ManualResetEvent signal = new ManualResetEvent(false);

using (NamedPipeServerStream stream = ...)
{
    var asyncResult = stream.BeginWaitForConnection(_ => signal.Set(), null);

    signal.WaitOne();
    if (asyncResult.IsCompleted)
    {
        stream.EndWaitForConnection(asyncResult);
        // success
    }
}

// in other thread
void cancel_Click(object sender, EventArgs e)
{
    signal.Set();
}


1 commentaires

Le signal doit également être réglé à l'intérieur d'un rappel transmis à BegwaitForConnection. Ensuite, l'exemple sera complet.



1
votes

Il n'y a aucun moyen de "soigneusement" fermer un fil de l'extérieur, si ce fil est en cours d'exécution du code non exploité. Il y a quelques façons de terminer brusquement le fil, mais ce n'est probablement pas ce que vous voulez.

Vous devez utiliser begwaitForConnection à la place.


0 commentaires

0
votes

En fait, la solution que j'ai utilisée (qui m'a eue été commise comme je l'écrivais de la question), après abandonner tous les threads, juste pour créer (et disposer immédiatement) un client pour chaque thread.

  threads.ForEach(thread=> thread.Abort());
  threads.ForEach(thread=>
              {
                   var client = new PipeClient(ServiceName); 
                   client.Connect(); 
                   client.Dispose();
              });


1 commentaires

Si vous accompagnez ce schéma fou, assurez-vous d'utiliser un délai d'attente approprié sur Connect, juste au cas où un autre processus établit une connexion au mauvais moment, ce qui entraîne l'abandon de l'écoute et ce fil à bloquer!