none
===== System.IO.File.AppendAllText 多线程下有点不靠谱 啊,==== RRS feed

  • 问题

  • 以下代码都是asp.net,我能预见到,如果多个客户端并发访问下面这个页面,asp.net从线程池中分配一个空闲的线程去服务这个请求。也就是可能存在多个线程并发访问log.txt文件。

     protected void Page_Load(object sender, EventArgs e)
            {
                string path = Server.MapPath("~/log.txt");
                for (int i = 0; i < 100000; i++)
                {
                    System.IO.File.AppendAllText(path, i.ToString());
                }
            }

    所以,我想那当然的加上了lock

     object locker = new object();
    
            protected void Page_Load(object sender, EventArgs e)
            {
                string path = Server.MapPath("~/log.txt");
    
                lock (locker)
                {
                    for (int i = 0; i < 100000; i++)
                    {
                        System.IO.File.AppendAllText(path, i.ToString());
                    }                               
                }
            }

    结果发现,出现文件被其它进程占用的IOException.

    这时,我又想,ReaderWriterLock锁应该是解决此类问题的。所以又改成了这样的代码:

    protected void Page_Load(object sender, EventArgs e)
            {
                string path = Server.MapPath("~/log.txt");
                System.Threading.ReaderWriterLock rwl = new System.Threading.ReaderWriterLock();
    
                rwl.AcquireWriterLock(1000);
    
                for (int i = 0; i < 100000; i++)
                {
                    System.IO.File.AppendAllText(path, i.ToString());
                }
    
                rwl.ReleaseWriterLock();
               
            }

    结果,涛声依旧。。。我有几点不明白:

    1\.net设计准则中说,可以确保所有静态方法是线程安全的,为什么这里却出现这种情况。

    2、如果一定要采用这个静态方法,有什么办法可以确保多个线程访问不会出现以上问题。谢谢。

    2012年3月20日 15:50

全部回复