J'étudie actuellement la manière dont Thread.Interrupt joue avec les appels P/Invoke ou natifs. J'ai lu dans MSDN qu'il n'est pas possible d'abandonner (Thread.Abort) un thread qui est dans l'appel natif (d'autres cas d'utilisation peuvent également s'appliquer). Mais je n'ai trouvé aucune référence qui indique la même chose pour les threads natifs qui sont dans l'état WaitSleepJoin.Interruption des threads natifs
Cette question n'est pas de savoir si l'on devrait appeler Abandonner ou Interrompre, mais plutôt où je peux trouver un document d'auteur à ce sujet. G-ing pour cela n'a pas fourni de sortie utile.
Mon exemple de test:
#ifdef NATIVEFUNCTIONS_EXPORTS
#define NATIVEFUNCTIONS_API __declspec(dllexport)
#else
#define NATIVEFUNCTIONS_API __declspec(dllimport)
#endif
#include <iostream>
extern "C"
{
NATIVEFUNCTIONS_API void EndlessWait(char const* mutexName)
{
std::cout << "entering the endless wait." << std::endl;
HANDLE mutex = CreateMutex(NULL, FALSE, mutexName);
WaitForSingleObject(mutex, INFINITE);
std::cout << "leaving the endless wait." << std::endl;
}
};
natif C++ - DLL qui exporte une fonction, qui ne cesse d'attendre sur un mutex.
Maintenant, le C# homologue .NET, qui tente d'annuler l'attente:
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace InterruptingNativeWaitingThread
{
class Program
{
[DllImport("NativeFunctions.dll", CharSet=CharSet.Ansi)]
static extern void EndlessWait(string str);
static void Main(string[] args)
{
string mutexName = "interprocess_mutex";
Mutex m = new Mutex(false, mutexName);
m.WaitOne();
Thread t = new Thread(() => { EndlessWait(mutexName); });
t.Start();
Thread.Sleep(1000);
t.Abort();
if(!t.Join(5000))
Console.WriteLine("Unable to terminate native thread.");
t.Interrupt();
if(!t.Join(5000))
Console.WriteLine("Unable to interrupt the native wait.");
Console.WriteLine("Release the mutex.");
m.ReleaseMutex();
t.Join();
}
}
}
L'exécution de cette application produit la sortie suivante:
entering the endless wait.
Unable to terminate native thread.
Unable to interrupt the native wait.
Release the mutex.
leaving the endless wait.
Abandonner ne fonctionne pas dans ce contexte comme prévu, mais msdn ne dit pas un mot sur l'interruption. Je m'attendrais à ce que cela fonctionne d'une part: puisque le thread géré étant dans l'état d'attente appelle également le WaitForSingleObject ou WaitForMultipleObjects natif; d'un autre côté, il y a une possibilité que le thread natif à interrompre ne supporte pas les exceptions, quoi?
Tout document est le bienvenu!
Un grand merci,
Ovanes
post-scriptum J'ai également trouvé dans MSDN que l'attente avorte jusqu'à ce que le thread à abandonner revienne du code non géré et de l'interruption du premier appel si le thread est dans l'état WaitSleepJoin et l'abandonne. Mais cela ne signifie pas que l'interruption ne peut pas interrompre WaitSleepJoin natif.
En effet, le thread est en état de fonctionnement. On dirait que .NET a sa propre gestion d'état des threads. Après la ligne avec l'appel à t.Abort() le thread est dans l'état AbortRequested, mais Thread.Interrupt ne l'interrompt pas, car il n'a jamais été dans l'état WaitSleepJoin. Merci beaucoup! – ovanes