try-cache-finally 在线程被杀掉时还有作用吗?
问题起因是因为在线程中申请了读写锁,如果一个线程被杀掉没有机会释放锁,那么杀掉线程就是一个很危险的操作,可能导致其他线程申请锁时被死锁。因此实验了一下。结论是即使线程被杀,try-cache-finally 依然有效,因为实际上抛出了线程终止异常ThreadAbortException,不多废话,看结果。
[TestFixture] private class Test { ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); class Locker : IDisposable { ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); public Locker(ReaderWriterLockSlim lockSlim) { _lock = lockSlim; _lock.EnterReadLock(); } public void Dispose() { if (_lock == null) return; var locker = _lock; _lock = null; locker.ExitReadLock(); Console.WriteLine("thread3 released"); } } [Test] public void TestMethod() { var t1 = new Thread(Thread1){Name = "thread1"}; var t2 = new Thread(Thread2) { Name = "thread2" }; var t3 = new Thread(Thread3) { Name = "thread3" }; t1.Start(); t2.Start(); t3.Start(); Thread.Sleep(300); t2.Abort(); t3.Abort(); Thread.Sleep(1000); t1.Abort(); t1.Join(); t2.Join(); t3.Join(); } public void Thread1() { Thread.Sleep(1000); _lock.EnterWriteLock(); Console.WriteLine("thread1 locked"); Thread.Sleep(5000); _lock.ExitWriteLock(); Console.WriteLine("thread1 released"); } public void Thread2() { _lock.EnterReadLock(); Console.WriteLine("thread2 locked"); try { while (true) { // NOP } } finally { _lock.ExitReadLock(); Console.WriteLine("thread2 released"); } } public void Thread3() { using (new Locker(_lock)) { Console.WriteLine("thread3 locked"); while (true) { // NOP } } } }
输出结果:
thread2 locked
thread3 locked
---- UNHANDLED EXCEPTION ----
Thread Name: thread2
System.Threading.ThreadAbortException: 正在中止线程。
在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread2() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 636
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
thread2 released
---- UNHANDLED EXCEPTION ----
Thread Name: thread3
System.Threading.ThreadAbortException: 正在中止线程。
在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread3() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 653
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
thread3 released
thread1 locked
---- UNHANDLED EXCEPTION ----
Thread Name: thread1
System.Threading.ThreadAbortException: 正在中止线程。
在 System.Threading.Thread.SleepInternal(Int32 millisecondsTimeout)
在 System.Threading.Thread.Sleep(Int32 millisecondsTimeout)
在 Wellcomm.Dts.Xmq.XmqQueue.Test.Thread1() 位置 D:\shwen\DotNetProjects\Wellcomm.Dts\Wellcomm.Dts.Xmq\XmqQueue.cs:行号 625
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()