多线程读写文件实现方法

  • Post author:
  • Post category:其他


总结:一般俩中方式 一种是file以共享属性打开,第二种用手动添加读写锁实现

using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Text;

namespace FileThread
{
    class MainClass
    {
        static void Main(string[] args) {
            //并发运行写入日志记录,由于多个线程同时写入同一个文件将会导致错误
            Parallel.For(0,LogCount,e => {
                WriteLog0();
                WriteLog1();

            });
            Console.WriteLine(string.Format("\r\n第一个文件 Log Count:{0}.\t\tWrited Count:{1}.\tFailed Count:{2}.",LogCount.ToString(),WritedCount0.ToString(),FailedCount0.ToString()));
            Console.WriteLine(string.Format("\r\n第二个文件 Log Count:{0}.\t\tWrited Count:{1}.\tFailed Count:{2}.",LogCount.ToString(),WritedCount1.ToString(),FailedCount1.ToString()));
            Console.Read();
        }

        static int LogCount = 2;
        static int FailedCount0 = 0;
        static int FailedCount1 = 0;

        static int WritedCount0 = 0;
        static int WritedCount1 = 0;

        static string filePath0 = "/Users/zhixian/Documents/unrealFront/projects/FileThread/logtext0.txt";
        static string filePath1 = "/Users/zhixian/Documents/unrealFront/projects/FileThread/logtext1.txt";

        static void WriteLog0() {
            try {
                //Stopwatch stopwatch = new Stopwatch();
                //stopwatch.Start();
                //stopwatch.ElapsedMilliseconds
                string logContent = string.Format("\r\n 无读写锁线程ID是{0},日期为{1}毫秒时间为{2},总写入次数{3} \r\n",Thread.CurrentThread.ManagedThreadId.ToString(),DateTime.Now.ToLongDateString() + "时间为" + DateTime.Now.ToLongTimeString(),DateTime.Now.Millisecond.ToString(),WritedCount0);
                byte[] logContentByte = Encoding.UTF8.GetBytes(logContent);
                FileStream fs = new FileStream(filePath0,FileMode.Append,FileAccess.Write,FileShare.ReadWrite);
                fs.Write(logContentByte,0,logContentByte.Length);
                fs.Dispose();
                fs.Close();
                WritedCount0++;
                Console.WriteLine("无读写锁 写入成功总数:" + WritedCount0);
            } catch(Exception ex) {
                FailedCount0++;
                Console.WriteLine("无读写锁 累计出错数:" + FailedCount0);
                Console.WriteLine(ex.Message);
            }
        }

        //读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入
        static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
        static void WriteLog1() {
            try {
                //Stopwatch stopwatch = new Stopwatch();
                //stopwatch.Start();
                //stopwatch.ElapsedMilliseconds
                //设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入
                //注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。
                //从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度
                //因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常
                Console.WriteLine("有读写锁 数据流格式 开始进入一个读写锁");
                LogWriteLock.EnterWriteLock();
                Console.WriteLine("#有读写锁 数据流格式 已经进入一个读写锁");

                string logContent = string.Format("\r\n 有读写锁 数据流格式 线程ID是{0},日期为{1}毫秒时间为{2},总写入次数{3} \r\n",Thread.CurrentThread.ManagedThreadId.ToString(),DateTime.Now.ToLongDateString() + "时间为" + DateTime.Now.ToLongTimeString(),DateTime.Now.Millisecond.ToString(),WritedCount1);
                byte[] logContentByte = Encoding.UTF8.GetBytes(logContent);
                FileStream fs = new FileStream(filePath1,FileMode.Append,FileAccess.Write);
                fs.Write(logContentByte,0,logContentByte.Length);
                fs.Dispose();
                fs.Close();

                //下面是file格式的写文件
                //var logContent = string.Format("\r\n 有读写锁 file格式 ID是{0},日期为{1}毫秒时间为{2},总写入次数{3} \r\n",Thread.CurrentThread.ManagedThreadId.ToString(),DateTime.Now.ToLongDateString() + "时间为" + DateTime.Now.ToLongTimeString(),DateTime.Now.Millisecond.ToString(),WritedCount2);
                //File.AppendAllText(filePath2,logContent);

                WritedCount1++;
                Console.WriteLine("有读写锁 数据流格式 写入成功总数:" + WritedCount1);
            } catch(Exception ex) {
                FailedCount1++;
                Console.WriteLine("有读写锁 数据流格式 累计出错数:" + FailedCount1);
                Console.WriteLine(ex.Message);
            } finally {
                //退出写入模式,释放资源占用
                //注意:一次请求对应一次释放
                //      若释放次数大于、小于 请求次数都将会触发异常[写入锁定未经保持即被释放等]
                Console.WriteLine("有读写锁 数据流格式 退出一个读写所锁");
                LogWriteLock.ExitWriteLock();
            }
        }
    }
}

运行结果



版权声明:本文为yuewei19原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。