ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

C# 多进程安全

2019-03-01 12:02:28  阅读:399  来源: 互联网

标签:前缀 安全 C# 互斥 线程 mutexKey 进程 mutex action


多个应用程序同时写入数据到一个文件中时可用

            public void WriteData(string dataWh, string filePath)
            {
                EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");
                waitHandle.WaitOne();
                try
                {
                    using (var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        byte[] dataAsByteArray = new UTF8Encoding(true).GetBytes(dataWh);
                        fs.Write(dataAsByteArray, 0, dataWh.Length);
                        Console.WriteLine("111111111111");
                    }
                }
                finally
                {
                    waitHandle.Set();
                }
            }
SHARED_BY_ALL_PROCESSES 是字符串键
确保所有应用程序中的键是一样的值, try里面的代码就是进程安全的.

可以复制这这段代码新建两个控制台程序试试 ^ ^


进阶补充(抄) 加入异常
        /// <summary>
        /// 进程间同步执行
        /// </summary>
        /// <param name="mutexKey">操作系统级的同步键
        /// (如果将 name 指定为 null 或空字符串,则创建一个局部互斥体。 
        /// 如果名称以前缀“Global\”开头,则 mutex 在所有终端服务器会话中均为可见。 
        /// 如果名称以前缀“Local\”开头,则 mutex 仅在创建它的终端服务器会话中可见。 
        /// 如果创建已命名 mutex 时不指定前缀,则它将采用前缀“Local\”。)</param>
        /// <param name="action">同步处理操作</param>
        public static void MutexExec(string mutexKey, Action action)
        {
            MutexExec(mutexKey: mutexKey, action: action, recursive: false);
        }

        /// <summary>
        /// 进程间同步执行
        /// </summary>
        /// <param name="mutexKey">操作系统级的同步键
        /// (如果将 name 指定为 null 或空字符串,则创建一个局部互斥体。 
        /// 如果名称以前缀“Global\”开头,则 mutex 在所有终端服务器会话中均为可见。 
        /// 如果名称以前缀“Local\”开头,则 mutex 仅在创建它的终端服务器会话中可见。 
        /// 如果创建已命名 mutex 时不指定前缀,则它将采用前缀“Local\”。)</param>
        /// <param name="action">同步处理操作</param>
        /// <param name="recursive">指示当前调用是否为递归处理,递归处理时检测到异常则抛出异常,避免进入无限递归</param>
        private static void MutexExec(string mutexKey, Action action, bool recursive)
        {
            //声明一个已命名的互斥体,实现进程间同步;该命名互斥体不存在则自动创建,已存在则直接获取
            //initiallyOwned: false:默认当前线程并不拥有已存在互斥体的所属权,即默认本线程并非为首次创建该命名互斥体的线程
            //注意:并发声明同名的命名互斥体时,若间隔时间过短,则可能同时声明了多个名称相同的互斥体,并且同名的多个互斥体之间并不同步,高并发用户请另行处理
            using (Mutex mut = new Mutex(initiallyOwned: false, name: mutexKey))
            {
                try
                {
                    //上锁,其他线程需等待释放锁之后才能执行处理;若其他线程已经上锁或优先上锁,则先等待其他线程执行完毕
                    mut.WaitOne();
                    //执行处理代码(在调用WaitHandle.WaitOne至WaitHandle.ReleaseMutex的时间段里,只有一个线程处理,其他线程都得等待释放锁后才能执行该代码段)
                    action();
                }
                //当其他进程已上锁且没有正常释放互斥锁时(譬如进程忽然关闭或退出),则会抛出AbandonedMutexException异常
                catch (AbandonedMutexException ex)
                {
                    //避免进入无限递归
                    if (recursive)
                        throw new Exception("避免进入无限递归", ex);

                    //非递归调用,由其他进程抛出互斥锁解锁异常时,重试执行
                    MutexExec(mutexKey: mutexKey, action: action, recursive: true);
                }
                finally
                {
                    //释放锁,让其他进程(或线程)得以继续执行
                    mut.ReleaseMutex();
                }
            }
        }

 




 

标签:前缀,安全,C#,互斥,线程,mutexKey,进程,mutex,action
来源: https://www.cnblogs.com/nocanstillbb/p/10455542.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有