ITPub博客

首页 > > > 关于.net线程安全问题

关于.net线程安全问题

作者:flynike 时间:2019-08-28 13:21:05 0 删除 编辑
public class Logger
    {
        
        private Queue<Action> queue;
        private ManualResetEvent manual;

       
        private Thread logThread;
        /// <summary>
        /// 指定存储文件的路径
        /// </summary>
        public static string Path { get; set; }

        //私有构造函数,初始化相关对象 使用单例模式
        private Logger()
        {
            queue = new Queue<Action>();
            manual = new ManualResetEvent(false);
            logThread = new Thread(Process);
            logThread.IsBackground = true;
            logThread.Start();
        }
        private readonly static Logger logger = new Logger();
        private static Logger GetInstance()
        {
            return logger;
        }
        //不断处理队列中的任务
        private void Process()
        {
            while (true)
            {
                
                manual.WaitOne();

             
                manual.Reset();

               
                Thread.Sleep(100);

              
                Queue<Action> copy;
                lock (queue)
                {
                    copy = new Queue<Action>(queue);
                    queue.Clear();
                    foreach (var action in copy)
                        action();
                } 
            }
        }
        private void ExcuteAction(string log)
        {
            string date = DateTime.Now.ToString();
            string path;
            if (!string.IsNullOrEmpty(Path))
                path = Path + "log.txt";
            else
                path = "log.txt";
            lock(queue)
            {
             
                queue.Enqueue(() => File.AppendAllText(path, log+" : "+date + Environment.NewLine));
            }
            
            manual.Set();
        }

        
        /// <summary>
        /// 将数据写入文件中
        /// </summary>
        /// <param name="log">要写入的数据</param>
        public static void WriteLog(string log)
        {
            // WriteLog 方法只是向队列中添加任务,执行时间极短,所以使用Task.Run。
            Task.Run(() =>
            {
                GetInstance().ExcuteAction(log);
            });
        }

}

 两条线程读写同一个对象,两条线程都lock这个对象
 用ManualResetEvent来控制读数据的线程(Thread(Process))
 当写数据的线程(Task.Run)有数据写入时开启读线程工作
 这样有可能控制并发,但测试几次,发现几次数据的顺序有误,但没有漏
主线程和新线程调用第三次后顺序没错 
开Task线程调用顺序完全相反,开始两次也会有些乱!!!!!!!!!!!!

.net技术多线程线程并发
问题补充:
调用代码

class Program
    {
        static void Main(string[] args)
        {
           

            //Task.Run(() => TestLogger());

            //TestLogger();

            new Thread(TestLogger).Start();
            
            Console.ReadKey();
        }
        static void TestLogger()
        {
            for (int i = 0; i < 50; i++)
            {
                Logger.WriteLog(i.ToString());
            }
        }
    }


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2618/viewspace-3169541/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: vue 命令找不到
请登录后发表评论 登录
全部评论

注册时间:2019-07-26

  • 博文量
    205
  • 访问量
    9820