Jak działa Thread.Abort ()?
Zwykle rzucamy wyjątek, gdy niepoprawne dane są przekazywane do metody lub gdy obiekt ma zamiar wprowadzić niepoprawny stan. Rozważmy następujący przykład
private void SomeMethod(string value)
{
if(value == null)
throw new ArgumentNullException("value");
//Method logic goes here
}
W powyższym przykładzie wstawiłem instrukcję rzucania, która rzucaArgumentNullException
. Moje pytanie brzmi: w jaki sposób środowisko wykonawcze potrafi wyrzucićThreadAbortException
. Oczywiście nie można użyćthrow
oświadczenie we wszystkich metodach, nawet w środowisku wykonawczym udaje się rzucićThreadAbortException
w naszych metodach niestandardowych.
Zastanawiałem się, jak oni to robią? Byłem ciekawy, co się dzieje za kulisami, otworzyłem reflektor, żeby go otworzyćThread.Abort
i skończyć z tym
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();//Implemented in CLR
Potem wyszukałem hasło i znalazłem toJak naprawdę działa ThreadAbortException. Ten link mówi, że środowisko wykonawcze przesyła APC przezQueueUserAPC
funkcja i tak robią sztuczkę. Nie byłem tego świadomyQueueUserAPC
metoda właśnie próbowałem sprawdzić, czy jest to możliwe przy użyciu jakiegoś kodu. Poniższy kod pokazuje moją próbę.
[DllImport("kernel32.dll")]
static extern uint QueueUserAPC(ApcDelegate pfnAPC, IntPtr hThread, UIntPtr dwData);
delegate void ApcDelegate(UIntPtr dwParam);
Thread t = new Thread(Threadproc);
t.Start();
//wait for thread to start
uint result = QueueUserAPC(APC, new IntPtr(nativeId), (UIntPtr)0);//returns zero(fails)
int error = Marshal.GetLastWin32Error();// error also zero
private static void APC(UIntPtr data)
{
Console.WriteLine("Callback invoked");
}
private static void Threadproc()
{
//some infinite loop with a sleep
}
Jeśli robię coś złego, wybacz mi, nie mam pojęcia, jak to zrobić. Znów wracam do pytania: Czy ktoś z wiedzą na temat tego lub części zespołu CLR może wyjaśnić, jak działa wewnętrznie? JeśliAPC
czy trik wynika z tego, co robię źle tutaj?