我正在使用此代码为另一个线程提供时间限制,并在一定时间后将其中断:
void RunWithTimeout(Action action, TimeSpan timeout)
{
AutoResetEvent signal = new AutoResetEvent(false);
Thread workerThread = null;
ThreadPool.QueueUserWorkItem((o) =>
{
workerThread = Thread.CurrentThread;
action();
signal.Set();
});
using (new Timer((o) => { signal.Set(); }, null, (int)timeout.TotalMilliseconds, Timeout.Infinite))
{
signal.WaitOne();
}
if (workerThread != null && workerThread.IsAlive)
{
try
{
workerThread.Abort();
}
catch { }
throw new System.TimeoutException();
}
}
我使用的是.NET 3.5,因此无法使用“任务”
我现在抛出TimeoutException,但是我想知道调用
Abort
时正在执行的行。有没有办法获取另一个线程的调用堆栈并将其传递给异常的
StackTrace
属性?
最佳答案
您不需要Timer
来等待另一个线程,可以使用WaitOne
重载来接受超时(以毫秒为单位)。
要捕获工作线程上的堆栈跟踪,可以通过闭合变量将ThreadAbortException
传递给主线程:
private static void RunWithTimeout(Action action, TimeSpan timeout)
{
Thread worker = null;
var signal = new AutoResetEvent(false);
ThreadAbortException abortException = null;
ThreadPool.QueueUserWorkItem(o =>
{
worker = Thread.CurrentThread;
try
{
action();
signal.Set();
}
catch (ThreadAbortException ex)
{
//thread is being aborted, pass the exception back to the main thread
abortException = ex;
}
});
if (!signal.WaitOne(timeout))
{
worker.Abort();
//abortException is now filled from the worker thread, the stack trace for the
//worker thread is now inside the InnerException of the ThreadAbortException
throw new TimeoutException("Operation timed out", abortException);
}
}
关于c# - 从另一个托管线程获取当前行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26672421/