C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#多线程互斥锁

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

作者:CHHC

这篇文章主要介绍了C#常用多线程(线程同步,事件触发,信号量,互斥锁,共享内存,消息队列),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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}]");
        }
    }
}

到此这篇关于C#常用多线程(线程同步,事件触发,信号量,互斥锁,共享内存,消息队列)的文章就介绍到这了,更多相关C#多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文