如何打破只包含受限执行区 (CER) 的循环
How to break out a loop contains only a constrained execution region (CER)
我正在使用受限执行区 (CER) 来保护线程的 while 循环内的代码部分:
private static void MyThreadFunc()
{
try {
...
while (true)
{
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
Thread.Sleep(1); // allow while loop to be broken out
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
问题是,如果我不在 while 循环末尾引入 Thread.Sleep(1)
语句,任何对线程调用 Thread.Abort() 的尝试都会挂起。有没有更好的方法在不使用 Thread.Sleep()
函数的情况下中止线程?
我不知道您为什么需要手动中止线程,因为 CLR 会在线程完成后执行此操作,或者使用 Thread.Join to wait until it terminates. But you can make use of the ManualResetEvent 优雅地中止它。
我通过将 while(true) 替换为 ManualResetEvent
对代码进行了一些更改
class ThreadManager
{
private ManualResetEvent shutdown = new ManualResetEvent(false);
private Thread thread;
public void start ()
{
thread = new Thread(MyThreadFunc);
thread.Name = "MyThreadFunc";
thread.IsBackground = true;
thread.Start();
}
public void Stop ()
{
shutdown.Set();
if (!thread.Join(2000)) //2 sec to stop
{
thread.Abort();
}
}
void MyThreadFunc ()
{
while (!shutdown.WaitOne(0))
{
// call with the work you need to do
try {
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
}
}
我正在使用受限执行区 (CER) 来保护线程的 while 循环内的代码部分:
private static void MyThreadFunc()
{
try {
...
while (true)
{
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
Thread.Sleep(1); // allow while loop to be broken out
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
问题是,如果我不在 while 循环末尾引入 Thread.Sleep(1)
语句,任何对线程调用 Thread.Abort() 的尝试都会挂起。有没有更好的方法在不使用 Thread.Sleep()
函数的情况下中止线程?
我不知道您为什么需要手动中止线程,因为 CLR 会在线程完成后执行此操作,或者使用 Thread.Join to wait until it terminates. But you can make use of the ManualResetEvent 优雅地中止它。
我通过将 while(true) 替换为 ManualResetEvent
对代码进行了一些更改class ThreadManager
{
private ManualResetEvent shutdown = new ManualResetEvent(false);
private Thread thread;
public void start ()
{
thread = new Thread(MyThreadFunc);
thread.Name = "MyThreadFunc";
thread.IsBackground = true;
thread.Start();
}
public void Stop ()
{
shutdown.Set();
if (!thread.Join(2000)) //2 sec to stop
{
thread.Abort();
}
}
void MyThreadFunc ()
{
while (!shutdown.WaitOne(0))
{
// call with the work you need to do
try {
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
}
}