Skip to content

Instantly share code, notes, and snippets.

@xdedss
Last active February 15, 2024 08:17
Show Gist options
  • Select an option

  • Save xdedss/ed9fb58ce31b3e3b165774b035ce65d3 to your computer and use it in GitHub Desktop.

Select an option

Save xdedss/ed9fb58ce31b3e3b165774b035ce65d3 to your computer and use it in GitHub Desktop.
An attempt to run actions with timeout in C#
using System;
using System.Threading;
public class TimeoutAction
{
private Thread timerThread;
private Thread mainThread;
private AutoResetEvent timerStartEvent = new AutoResetEvent(false);
private AutoResetEvent timerPreparedEvent = new AutoResetEvent(false);
long timeoutTicks;
object locker = new object();
public TimeoutAction()
{
timerThread = new Thread(() => {
while (true) // this timer thread will be reused so that there is no need to creat a new one each time.
{
timerStartEvent.WaitOne(); // wait for next action
try
{
timerPreparedEvent.Set(); // notify the main thread
Thread.Sleep(15); // minimum resolution
while (DateTime.Now.Ticks < timeoutTicks)
{
Thread.Sleep(5);
}
Thread.Sleep(0);
lock (locker) // perhaps this is necessary to prevent two threads from fighting against each other
{
mainThread.Abort();
}
}
catch (ThreadInterruptedException)
{
// this means that the action in the main thread is completed
}
}
});
timerThread.Start();
}
public void Run(Action action, int millisecondsTimeout)
{
mainThread = Thread.CurrentThread; // whichever thread that calls this method. doesn't have to be the real main thread
timeoutTicks = DateTime.Now.Ticks + millisecondsTimeout * 10000L; // 1ms = 10000Ticks
timerStartEvent.Set(); // notify the timer thread
timerPreparedEvent.WaitOne(1000); // wait for the timer thread to be ready
try
{
action();
}
catch (ThreadAbortException) // timeout!
{
Thread.ResetAbort();
throw new TimeoutException();
}
catch (Exception ex)
{
lock (locker)
{
timerThread.Interrupt();
}
throw new Exception("Exception during execution: ", ex);
}
lock (locker)
{
timerThread.Interrupt();
}
}
~TimeoutAction()
{
if (timerThread != null)
{
timerThread.Abort();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment