C#常用多线程(线程同步,事件触发,信号量,互斥锁,共享内存,消息队列)

复制代码
using System;
using System.Threading;
using System.Windows.Forms;
using UtilForm.Util;

namespace UtilForm
{
    // 线程同步,事件触发,信号量,互斥锁,共享内存,消息队列
    public partial class frmUIThread : Form
    { 
        SynchronizationContext context;// 子线程同步到主线程 
       
        public delegate void DoSth(object sender); // 事件触发
        public event DoSth OnMyEvent;

        Mutex mutex = new Mutex(); // 互斥锁,锁住某一资源 
        ManualResetEvent manualReset = new ManualResetEvent(false); // 信号量,流程上锁定,A执行完再执行B  

        public frmUIThread()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        { 
            context = SynchronizationContext.Current; 
            OnMyEvent += new DoSth(ProgressEvent);
            Console.WriteLine("主线程id:" + Thread.CurrentThread.ManagedThreadId);

            // 线程同步
            ThreadPool.QueueUserWorkItem(state =>
            {
                Console.WriteLine("子线程id:" + Thread.CurrentThread.ManagedThreadId);

                for (int i = 0; i < 3; ++i)
                {
                    //textBox1.Text = i.ToString();//:“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”
                    //
                    // 写法1:
                    //textBox1.BeginInvoke((MethodInvoker)delegate
                    //{
                    //    textBox1.Text = i.ToString();
                    //});
                    //
                    //
                    // 写法2:
                    context.Send(ProgressUI, i);

                    if (2 == i)
                    {
                        OnMyEvent(i);// 线程间回调
                    }
                    Thread.Sleep(100);
                }
            });

            // 模拟互斥量
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThdMutex));
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThdMutex));

            // 模拟信号量在B流程中阻塞,A流程结束,继续B流程
            ThreadPool.QueueUserWorkItem(state =>
            {
                Console.WriteLine("模拟信号量,A开始执行");
                Thread.Sleep(5000);
                manualReset.Set();// 释放
                Console.WriteLine("模拟信号量,A执行完成");
            });
            ThreadPool.QueueUserWorkItem(state =>
            {
                Console.WriteLine("模拟信号量,B等待执行");
                manualReset.Reset();// 重置信号量 
                manualReset.WaitOne();// 停止
                //manualReset.WaitOne(2000);// 带超时停止
                Console.WriteLine("模拟信号量,B执行完成");
            }); 

            // 共享内存 
            ThreadPool.QueueUserWorkItem(state =>
            {
                MemoryCacheHelper.SetCache("10001", "123");
            });
            ThreadPool.QueueUserWorkItem(state =>
            {
                Thread.Sleep(5000);
                var val = MemoryCacheHelper.GetCache("10001");
                Console.WriteLine($"共享内存:{val}");
            });
        }

        /// <summary>
        /// 更新UI
        /// </summary>
        /// <param name="obj"></param>
        private void ProgressUI(object obj)
        {
            Console.WriteLine("更新UI线程::当前线程id:" + Thread.CurrentThread.ManagedThreadId);

            textBox1.Text = obj.ToString();
        }

        /// <summary>
        /// 事件处理
        /// </summary>
        private void ProgressEvent(object sender)
        {
            Console.WriteLine($"线程事件触发:{sender.ToString()}");
        }

        void ThdMutex(object obj)
        {
            mutex.WaitOne();

            Console.WriteLine($"互斥线程 {Thread.CurrentThread.ManagedThreadId} 正在执行任务");

            Thread.Sleep(1000);

            Console.WriteLine($"互斥线程 {Thread.CurrentThread.ManagedThreadId} 任务执行完毕");

            mutex.ReleaseMutex(); 
        }
    }
}
复制代码
using System;
using System.Runtime.Caching;

namespace UtilForm.Util
{
    public class MemoryCacheHelper
    {
        private static MemoryCache cache = MemoryCache.Default;// MemoryCache ObjectCache

        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetCache(string key)
        {
            var obj = cache.Get(key);
            //Console.WriteLine($"-读取缓存[{key}]:{JsonConvert.SerializeObject(obj, Formatting.Indented)}");
            return obj;
        }

        /// <summary>
        /// 写入缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        /// <param name="timeout">过期时间,默认7200秒</param>
        public static void SetCache(string key, object obj, int timeout = 7200)
        {
            cache.Set(key, obj, DateTimeOffset.Now.AddSeconds(timeout));
            //Console.WriteLine($"-写入缓存[{key}]:{JsonConvert.SerializeObject(obj, Formatting.Indented)}");
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        public static void RemoveCache(string key)
        {
            cache.Remove(key);
            //Console.WriteLine($"-移除缓存[{key}]");
        }
    }
}
相关推荐
SomeOtherTime3 小时前
Rust所有权(AI回答)
开发语言·后端·rust
Easyhood3 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青4 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
饮水桶_T8 小时前
JAVA IO流笔记
开发语言·数据结构·算法
Felven10 小时前
C. Brr Brrr Patapim
c语言·开发语言
路溪非溪11 小时前
python标准库使用总结
开发语言·python
SomeOtherTime13 小时前
Rust 面向对象介绍(AI回答)
开发语言·python·rust
zh_xuan13 小时前
kotlin常见面试题
开发语言·kotlin·面试题
草莓熊Lotso15 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
huaqianzkh16 小时前
WinForm C#:循环修改控件UI闪烁卡顿?SuspendLayout / ResumeLayout 与 BeginUpdate 优化
开发语言·ui·c#