Обычно мы генерируем исключение, когда неверный ввод передается методу или когда объект собирается ввести недопустимое состояние. Рассмотрим следующий пример
private void SomeMethod(string value)
{
if(value == null)
throw new ArgumentNullException("value");
//Method logic goes here
}
В приведенном выше примере я вставил оператор throw, который выдает ArgumentNullException
. Мой вопрос заключается в том, как runtime удается бросить ThreadAbortException
. Очевидно, что во всех методах невозможно использовать оператор throw
, даже время выполнения управляет тем, что бросает ThreadAbortException
в наши собственные методы.
Мне было интересно, как они это делают?
Мне было любопытно узнать, что происходит за кулисами, я открыл рефлектор, чтобы открыть Thread.Abort
и в конечном итоге с этим
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();//Implemented in CLR
Затем я googled и нашел это Как работает ThreadAbortException. Эта ссылка говорит, что runtime отправляет APC через QueueUserAPC
функцию и то, как они делают трюк.
Я не знал о методе QueueUserAPC
, я просто попытался выяснить, возможно ли это с помощью некоторого кода. Следующий код показывает мою попытку.
[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
}
Если я делаю что-то неправильно, простите меня, я понятия не имею, как это сделать. Снова вернемся к вопросу. Может ли кто-нибудь, кто знает об этом или части команды CLR, объяснить, как он работает внутри страны?
Если APC
- это трюк, выполняющийся после того, что вы делаете неправильно здесь?