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}]");
        }
    }
}
相关推荐
简单点了17 分钟前
SM4加密算法
java·开发语言
aFakeProgramer1 小时前
使用 ROS2 构建客户端-服务器通信:一个简单的计算器示例
开发语言·python·ros2
ALex_zry1 小时前
Golang云端编程入门指南:前沿框架与技术全景解析
开发语言·后端·golang
jinlei20092 小时前
在python 代码中调用rust 源码库操作步骤
开发语言·python·rust
float_六七2 小时前
Apache Commons Lang 3
开发语言·python·apache
枫叶丹43 小时前
【Qt开发】常用控件(七)-> styleSheet
开发语言·css·qt·qss
新停浊酒杯3 小时前
简单介绍——Java注解的本质
java·开发语言
3分云计算3 小时前
流水线用到的Dockerfile和构建脚本build.sh
java·开发语言
唐青枫5 小时前
LinqToDB 从入门到精通:示例驱动教程
c#·.net