• 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}");
                });
            }
    
            /// 
            /// 更新UI
            /// 
            /// 
            private void ProgressUI(object obj)
            {
                Console.WriteLine("更新UI线程::当前线程id:" + Thread.CurrentThread.ManagedThreadId);
    
                textBox1.Text = obj.ToString();
            }
    
            /// 
            /// 事件处理
            /// 
            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
    
            /// 
            /// 读取缓存
            /// 
            /// 
            /// 
            public static object GetCache(string key)
            {
                var obj = cache.Get(key);
                //Console.WriteLine($"-读取缓存[{key}]:{JsonConvert.SerializeObject(obj, Formatting.Indented)}");
                return obj;
            }
    
            /// 
            /// 写入缓存
            /// 
            /// 
            /// 
            /// 过期时间,默认7200秒
            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)}");
            }
    
            /// 
            /// 删除缓存
            /// 
            /// 
            public static void RemoveCache(string key)
            {
                cache.Remove(key);
                //Console.WriteLine($"-移除缓存[{key}]");
            }
        }
    }

    复制代码

  • 相关阅读:
    基于Springboot+mysql的闲置二手交易网站系统设计
    数字孪生论文阅读笔记【3】
    湖仓一体电商项目(二):项目使用技术及版本和基础环境准备
    02Redis的命令行客户端和桌面客户端的下载和安装
    如果你想跨行转做数据分析师,劝你慎重
    centos7安装ansible图形化管理界面AWX
    A Survey on Neural Network Interpretability
    如何安装最新版Docker Compose?
    RabbitMQ原理(四):MQ的可靠性
    百度飞桨AI4S亮相全国动力学设计与反问题研讨会,助力汽车底盘智能设计
  • 原文地址:https://blog.csdn.net/arno1988/article/details/132661433