You should get a ThreadAbortException, and unless you are using threading or tasks, that will cancel the running code. If you are using threading or tasks, you'd have to catch the exception and cancel them.
I tested with this code
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Threading;
using Microsoft.SqlServer.Server;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static int ClrDelay(int durationMs, bool spin = false)
{
var sw = new Stopwatch();
sw.Start();
try
{
while (sw.ElapsedMilliseconds < durationMs)
{
if (spin)
{
Thread.SpinWait(10);
}
else
{
Thread.Sleep(10);
}
}
return durationMs;
}
catch (Exception ex)
{
System.IO.File.WriteAllText("c:\\temp\\out.txt", $"Catch at {DateTime.Now} {ex}");
throw;
}
catch
{
System.IO.File.WriteAllText("c:\\temp\\out.txt", "Catch");
throw;
}
}
}
And the output after running
select dbo.clrdelay(10000,0)
and canceling in SSMS is
PS C:\temp> cat .\out.txt
Catch at 9/11/2025 10:29:43 AM System.Threading.ThreadAbortException: Thread was being aborted.
at Microsoft.Win32.SafeNativeMethods.QueryPerformanceCounter(Int64& value)
at System.Diagnostics.Stopwatch.GetTimestamp()
at System.Diagnostics.Stopwatch.GetRawElapsedTicks()
at System.Diagnostics.Stopwatch.GetElapsedDateTimeTicks()
at System.Diagnostics.Stopwatch.get_ElapsedMilliseconds()
at UserDefinedFunctions.ClrDelay(Int32 durationMs, Boolean spin)
sp_execute_external_scriptsp_execute_external_scriptto and from the code as aDataFrame.