C# .netframework 4.5 下的 lock 语法 已经够用了,挺安全的。

如果你在一个线程里用 lock语法  锁住了某段数据,当外部粗暴的 abort 或 interrupt 这个线程后,退出线程前,这个 lock 会自动释放了。

我做了一个简单的例子来模拟情况,先是写了一个 类 Class2,里面有一个 int _count 用来在线程间互斥的修改,用一个 _locker 来保护。

提供了四个方法:

start(),创建线程并运行。运行起来,先会用 lock(_locker) 加锁保护,在保护内 _count 加1,然后,就sleep这个线程1小时。1小时到期后,会退出锁保护。

abort(),interrupt(),都会触发上面那个线程中断。

 add(),先会用 lock(_locker) 加锁保护,在保护内 _count 加1,再退出锁保护。

 

然后创建一个FORM,在这个FORM 上有四个按键,一个是创建线程并运行(start thread),另一个是 abort 这个线程,还有一个是 interrupt 这个线程,最后一个是 add 一个值。注意因为 add 时会被锁住,所以,add 这里又创建一个线程去 调用 上面那个类里的 add,这样,界面上的 add 就可以反复按而不住卡住 FORM 主线程。

这是那个 Class2.cs。

复制代码
using System;
using System.Threading;
using System.Diagnostics;

namespace testThreadForm
{
    public class Class2
    {
        private object _locker = new object();
        private Thread _t = null;
        private int _count = 0;

        public void Start()
        {
            Debug.WriteLine("[{0}] Start: BEGIN.", Thread.CurrentThread.ManagedThreadId);
            if (null != _t)
            {
                _t.Abort();
                _t.Join();
                _t = null;
            }

            _t = new Thread(new ThreadStart(_backgroundLoop));
            _t.Start();
            Debug.WriteLine("[{0}] Start: END.", Thread.CurrentThread.ManagedThreadId);
        }

        public void Interrupt()
        {
            Debug.WriteLine("[{0}] Interrupt: BEGIN.", Thread.CurrentThread.ManagedThreadId);
            if (null != _t)
            {
                _t.Interrupt();
            }
            Debug.WriteLine("[{0}] Interrupt: END.", Thread.CurrentThread.ManagedThreadId);
        }

        public void Abort()
        {
            Debug.WriteLine("[{0}] Abort: BEGIN.", Thread.CurrentThread.ManagedThreadId);
            if (null != _t)
            {
                _t.Abort();
            }
            Debug.WriteLine("[{0}] Abort: END.", Thread.CurrentThread.ManagedThreadId);
        }

        public void Add()
        {
            Debug.WriteLine("[{0}] Add: BEGIN.", Thread.CurrentThread.ManagedThreadId);
            lock (_locker)
            {
                ++_count;
                Debug.WriteLine("[{1}] ADD: count = {0}", _count, Thread.CurrentThread.ManagedThreadId);
            }
            Debug.WriteLine("[{0}] Add: END.", Thread.CurrentThread.ManagedThreadId);
        }

        private void _backgroundLoop()
        {
            Debug.WriteLine("[{0}] Loop: BEGIN.", Thread.CurrentThread.ManagedThreadId);
            try
            {
                lock (_locker)
                {
                    _count++;
                    Thread.Sleep(1000 * 60 * 60);
                }
            }
            catch (ThreadInterruptedException)
            {
                Debug.WriteLine("[{0}] Loop: ThreadInterruptedException awoken.",
                          Thread.CurrentThread.ManagedThreadId);
            }
            catch (ThreadAbortException)
            {
                Debug.WriteLine("[{0}] Loop: ThreadAbortException aborted.",
                                  Thread.CurrentThread.ManagedThreadId);
            }
            finally
            {
                Debug.WriteLine("[{0}] Loop: END.", Thread.CurrentThread.ManagedThreadId);
            }
        }
    }
}
复制代码

这是 主 FORM 里的调用。

复制代码
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace testThreadForm
{
    public partial class Form1 : Form
    {
        Class2 c = new Class2();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            c.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            c.Abort();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(_add));
            t.Start();
        }

        private void _add()
        {
            Debug.WriteLine("[{0}] _add: BEGIN", Thread.CurrentThread.ManagedThreadId);
            c.Add();
            Debug.WriteLine("[{0}] _add: END", Thread.CurrentThread.ManagedThreadId);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            c.Interrupt();
        }
    }
}
复制代码

这是按如下操作后的结果:

1)按下 start thread

2)按下 add 

3)按下 abort

4)按下 start thread

5)按下 add

6)按下 interrupt

复制代码
[1] Start: BEGIN.
[1] Start: END.
[3] Loop: BEGIN.
[4] _add: BEGIN
[4] Add: BEGIN.
[1] Abort: BEGIN.
Exception thrown: 'System.Threading.ThreadAbortException' in mscorlib.dll
[4] ADD: count = 2
[3] Loop: ThreadAbortException aborted.
Exception thrown: 'System.Threading.ThreadAbortException' in testThreadForm.exe
[4] Add: END.
[3] Loop: END.
[1] Abort: END.
The thread 0x6578 has exited with code 0 (0x0).
[4] _add: END
The thread 0x2508 has exited with code 0 (0x0).

[1] Start: BEGIN.
[1] Start: END.
[5] Loop: BEGIN.
[6] _add: BEGIN
[6] Add: BEGIN.
[1] Interrupt: BEGIN.
[1] Interrupt: END.
Exception thrown: 'System.Threading.ThreadInterruptedException' in mscorlib.dll
[5] Loop: ThreadInterruptedException awoken.
[6] ADD: count = 4
[6] Add: END.
[6] _add: END
The thread 0x5fc has exited with code 0 (0x0).
[5] Loop: END.
The thread 0x4994 has exited with code 0 (0x0).
复制代码

 

posted @   PencilStart  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示