unconditional thread abort

  • Thread starter Thread starter Azmodan
  • Start date Start date
A

Azmodan

I want to abort (kill) a thread no matter what. In the documentation it
says that if the thread is in an unmanaged code portion when the
ThreadAbortException is thrown, the system will rethrow it when managed
code is executed. But what if the thread is stuck in an unmanaged
method? how can I kill the thread?

(as a side note, Socket.Receive() appears to be unmanaged!!! )

here is a small sample that uses 2 threads that get hung in a
socket.receive and cannot be aborted. (i wanted them to get hunged!). If
the socket part is commented, it works!



using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
///

class MyThread
{
public MyThread()
{
}

public void run()
{
int i=0;
int k=0;
Console.WriteLine("init thread " + this.GetHashCode());
while(true)
{
Console.WriteLine("thread " + this.GetHashCode() + "
" + i++);
Thread.Sleep(1000);

//----begin socket part---
Socket sock = new
Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

//bogus address,
nothigs come from here so that the Receive method will run forever!
IPAddress hostIPAddress1 =
(Dns.Resolve("europe.battle.net")).AddressList[0];
sock.Connect(new IPEndPoint(hostIPAddress1,80));
byte[] bytes = new byte[256];
k=sock.Receive(bytes);
Console.WriteLine("Received " + k + " bytes");
//---end socket part---
}
}
}

class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Start();
}

public static void Start()
{
MyThread myTh1 = new MyThread();
Thread th1 = new Thread(new ThreadStart(myTh1.run));
th1.Name="TH1";
th1.Start();

MyThread myTh2 = new MyThread();
Thread th2 = new Thread(new ThreadStart(myTh2.run));
th2.Name="TH2";
th2.Start();

Thread.Sleep(5000);

th1.Abort();
Thread.Sleep(500);
Console.WriteLine("th1 aborted -> status: " +
th1.ThreadState.ToString());

Thread.Sleep(6000);

th2.Abort();
Thread.Sleep(500);
Console.WriteLine("th2 aborted -> status: " +
th2.ThreadState.ToString());

}
}
}
 
Azmodan said:
I want to abort (kill) a thread no matter what. In the documentation it
says that if the thread is in an unmanaged code portion when the
ThreadAbortException is thrown, the system will rethrow it when managed
code is executed. But what if the thread is stuck in an unmanaged
method? how can I kill the thread?

The only absolutely guaranteed way to kill it at that point is to exit the
application.

There are other conditions where the runtime cannot abort a thread; e.g. the
thread may be suspended, and it must be running for the abort notification
to be delivered to the managed thread.

Another method you might employ is to run the thread in a separate
appdomain, and if you cannot abort it you can unload the appdomain. The
runtime goes to extra lengths to unload an appdomain that it does not do
when you just call abort, but even this will not guarantee that the thread
gets terminated.

Also, make sure you mark each thread as Background, otherwise you will have
trouble exiting your application if the thread hangs.
(as a side note, Socket.Receive() appears to be unmanaged!!! )

You should be able to close the socket to make it return from the call to
Receive.

here is a small sample that uses 2 threads that get hung in a
socket.receive and cannot be aborted. (i wanted them to get hunged!). If
the socket part is commented, it works!



using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
///

class MyThread
{
public MyThread()
{
}

public void run()
{
int i=0;
int k=0;
Console.WriteLine("init thread " + this.GetHashCode());
while(true)
{
Console.WriteLine("thread " + this.GetHashCode() + "
" + i++);
Thread.Sleep(1000);

//----begin socket part---
Socket sock = new
Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

//bogus address,
nothigs come from here so that the Receive method will run forever!
IPAddress hostIPAddress1 =
(Dns.Resolve("europe.battle.net")).AddressList[0];
sock.Connect(new IPEndPoint(hostIPAddress1,80));
byte[] bytes = new byte[256];
k=sock.Receive(bytes);
Console.WriteLine("Received " + k + " bytes");
//---end socket part---
}
}
}

class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Start();
}

public static void Start()
{
MyThread myTh1 = new MyThread();
Thread th1 = new Thread(new ThreadStart(myTh1.run));
th1.Name="TH1";
th1.Start();

MyThread myTh2 = new MyThread();
Thread th2 = new Thread(new ThreadStart(myTh2.run));
th2.Name="TH2";
th2.Start();

Thread.Sleep(5000);

th1.Abort();
Thread.Sleep(500);
Console.WriteLine("th1 aborted -> status: " +
th1.ThreadState.ToString());

Thread.Sleep(6000);

th2.Abort();
Thread.Sleep(500);
Console.WriteLine("th2 aborted -> status: " +
th2.ThreadState.ToString());

}
}
}
 
Pai nu prea se poate. Imagineaza un thread care incearca sa fac o alocare
din process heap, a executat EnterCriticalSection
pe lock-ul heap-ului dupa care alt thread executa TerminateThread. Nici
macar exit process un mai functioneaza dupa asta.

In CLR e posibil sa arunci un ThreadAbortException deoarece toate lock-urile
sunt mentinute de runtime. Chiar si aici nu
se mai poate garanta nimic in process si un exit e binevenit (de exemplu, sa
zicem ca un thread incearca sa faca update la
o structura si necesita multiple operatiuni ca s-o mentine coerenta - daca
threadul moare, structura nu mai are nici o valoare;
se poate scrie cod care se asteapta ca orice structura interna sa fie in
orice stare? nu cred).

Daca totusi ai nevoie, poti avea un AppDomain separat pe care sa-l descarci
cind suspectezi un hang.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


Azmodan said:
I want to abort (kill) a thread no matter what. In the documentation it
says that if the thread is in an unmanaged code portion when the
ThreadAbortException is thrown, the system will rethrow it when managed
code is executed. But what if the thread is stuck in an unmanaged
method? how can I kill the thread?

(as a side note, Socket.Receive() appears to be unmanaged!!! )

here is a small sample that uses 2 threads that get hung in a
socket.receive and cannot be aborted. (i wanted them to get hunged!). If
the socket part is commented, it works!



using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication2
{
/// <summary>
/// Summary description for Class1.
/// </summary>
///

class MyThread
{
public MyThread()
{
}

public void run()
{
int i=0;
int k=0;
Console.WriteLine("init thread " + this.GetHashCode());
while(true)
{
Console.WriteLine("thread " + this.GetHashCode() + "
" + i++);
Thread.Sleep(1000);

//----begin socket part---
Socket sock = new
Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

//bogus address,
nothigs come from here so that the Receive method will run forever!
IPAddress hostIPAddress1 =
(Dns.Resolve("europe.battle.net")).AddressList[0];
sock.Connect(new IPEndPoint(hostIPAddress1,80));
byte[] bytes = new byte[256];
k=sock.Receive(bytes);
Console.WriteLine("Received " + k + " bytes");
//---end socket part---
}
}
}

class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Start();
}

public static void Start()
{
MyThread myTh1 = new MyThread();
Thread th1 = new Thread(new ThreadStart(myTh1.run));
th1.Name="TH1";
th1.Start();

MyThread myTh2 = new MyThread();
Thread th2 = new Thread(new ThreadStart(myTh2.run));
th2.Name="TH2";
th2.Start();

Thread.Sleep(5000);

th1.Abort();
Thread.Sleep(500);
Console.WriteLine("th1 aborted -> status: " +
th1.ThreadState.ToString());

Thread.Sleep(6000);

th2.Abort();
Thread.Sleep(500);
Console.WriteLine("th2 aborted -> status: " +
th2.ThreadState.ToString());

}
}
}
 
Back
Top