询问者
===== System.IO.File.AppendAllText 多线程下有点不靠谱 啊,====

问题
-
以下代码都是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、如果一定要采用这个静态方法,有什么办法可以确保多个线程访问不会出现以上问题。谢谢。
全部回复
-
这…Web环境原本就是多线程了
所以没这样的写法如果您想分享文件的写入权限的話,您应该用FileShare.Write或FileShare.ReadWrite
Example:
string path = Server.MapPath("~/log.txt");
FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write);
StreamWriter sw = new StreamWriter(fs);
for (int i = 0; i < 100000; i++)
{
sw.WriteLine(i.ToString());
}
sw.Close();
fs.Close();
http://msdn.microsoft.com/zh-cn/library/system.io.fileshare(v=vs.100).aspx
- The blog of typewriter職人
- Convert C# to VB.NET
- /*If my concept is wrong ,please correct me.Thanks.*/
- 已编辑 Shadow .Net 2012年3月20日 16:03