You can use threads, but they must behave. Otherwise you'll lose the benefits of using them.
From the CLR Host Environment
How SQL Server and the CLR Work Together
This section discusses how SQL Server integrates the threading,
  scheduling, synchronization, and memory management models of SQL
  Server and the CLR. In particular, this section examines the
  integration in light of scalability, reliability, and security goals.
  SQL Server essentially acts as the operating system for the CLR when
  it is hosted inside SQL Server. The CLR calls low-level routines
  implemented by SQL Server for threading, scheduling, synchronization,
  and memory management. These are the same primitives that the rest of
  the SQL Server engine uses. This approach provides several
  scalability, reliability, and security benefits.
Scalability: Common threading, scheduling, and synchronization
CLR calls SQL Server APIs for creating threads, both for running user
  code and for its own internal use. In order to synchronize between
  multiple threads, the CLR calls SQL Server synchronization objects.
  This allows the SQL Server scheduler to schedule other tasks when a
  thread is waiting on a synchronization object. For example, when the
  CLR initiates garbage collection, all of its threads wait for garbage
  collection to finish. Because the CLR threads and the synchronization
  objects they are waiting on are known to the SQL Server scheduler, SQL
  Server can schedule threads that are running other database tasks not
  involving the CLR. This also enables SQL Server to detect deadlocks
  that involve locks taken by CLR synchronization objects and employ
  traditional techniques for deadlock removal.
Managed code runs preemptively in SQL Server. The SQL Server scheduler
  has the ability to detect and stop threads that have not yielded for a
  significant amount of time. The ability to hook CLR threads to SQL
  Server threads implies that the SQL Server scheduler can identify
  "runaway" threads in the CLR and manage their priority. Such runaway
  threads are suspended and put back in the queue. Threads that are
  repeatedly identified as runaway threads are not allowed to run for a
  given period of time so that other executing workers can run.