C# 高性能写文件 —— 只为挨砖

路人乙e 2011-02-25 04:57:04
说到写文件,开源项目log4net对于.NET程序员来说恐怕是无人不知,本人一直想写一个性能高效的日志组件,但能力有限,因此来向大家学习,还望各位仁兄不吝赐教。

小弟写了一个简单的写文件的组件,经测试可以支撑5000的并发量(5000线程同时写同一个文件),再大的没测试,因为5000已经把CPU几乎沾满了。

贴出全部代码供大家探讨。

项目很简单,包含4个类:

FileAppender 基础类,提供写文件操作(私有)

IOLock 对读写线程锁的封装(私有)

Logger 对外提供写文件入口(公开)

Log 只是一个使用Logger的案例(公开)

代码请看博文:
CSDN:http://blog.csdn.net/sq_zhuyi/archive/2011/02/25/6207970.aspx
博客园:http://www.cnblogs.com/sqzhuyi/archive/2011/02/25/io.html

完整代码下载:
http://files.cnblogs.com/sqzhuyi/Zhuyi.IO.rar

...全文
796 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
路人乙e 2011-02-27
  • 打赏
  • 举报
回复
我再次重申一次,我想要实现“高性能”,以上代码是我及其有限的思维,我对文件操作没什么经验,我是来请教的!请多多指正!
兔子-顾问 2011-02-26
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 winner2050 的回复:]
减少 IO 次数就很高性能了。
[/Quote]
减少io,系统本身就这么做的,写文件的第一步是写到缓存,但是保证健壮性,还是不能少,怕突然断电。
winner2050 2011-02-26
  • 打赏
  • 举报
回复

减少 IO 次数就很高性能了。
兔子-顾问 2011-02-26
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 sp1234 的回复:]
如果是“高性能”地在文件最后追加内容(注意说成“并发写文件”是很容易歧义的),其实这个高性能,其设计基础是——根本不写文件,而只是写到内存队列中。然后只有唯一的一个线程去写文件(当队列空了,则线程结束;当有第一个内容加入队列,则向系统线程池中注册一个写文件线程)。
[/Quote]

+1

没在楼主代码中看出高性能的体现,到是觉得你的loger类可能会有并发,产生IOException。互斥应该写在可能并发的地方。不说实际应用如何使用,既然内部用了Threading.Timer,里面会调用dispose,那dispose就必须和其他的io操作互斥,否则,你关闭了文件,另外一边又写,就异常了。

高性能应该是弄个queue,把写的任务扔进去,然后使能一个线程去操作。
linkhoo1 2011-02-26
  • 打赏
  • 举报
回复
既然有锁,何来并发?

------如能给个并发的精确定义?是不是单核时代就不存在并发?
  • 打赏
  • 举报
回复
如果是“高性能”地在文件最后追加内容(注意说成“并发写文件”是很容易歧义的),其实这个高性能,其设计基础是——根本不写文件,而只是写到内存队列中。然后只有唯一的一个线程去写文件(当队列空了,则线程结束;当有第一个内容加入队列,则向系统线程池中注册一个写文件线程)。
doubleu2005 2011-02-25
  • 打赏
  • 举报
回复
攒钱买砖狠拍!
  • 打赏
  • 举报
回复
既然有锁,何来并发?
szysslszy 2011-02-25
  • 打赏
  • 举报
回复
好砖,抛出来的不错
636f6c696e 2011-02-25
  • 打赏
  • 举报
回复
好文章!正在学这方面的东西,太有参考价值了!下载收藏了!谢谢!
bloodish 2011-02-25
  • 打赏
  • 举报
回复
性能高不高没有用过,说几点觉得可以改进的地方.

1) IOLock没有必要对ReaderWriterLock再次封装,看不出封装的优点
2) 精准的时间控制和判断,建议用Stopwatch,不建议TimeSpan来判断
3) 你实现了IDisposable接口,但又没有按标准的Dispose模式实现Dispose,这样就没有实现IDisposable接口的必要了.
4) 用Dictionary请用TryGetValue取值,不建议用ContiansKey先判断是否存在某个Key,再取值
5) 如果你在用.Net4.0,
private void WriteText(string content, bool append)  

改成缺省参数写法,也许代码会更好看些
private void WriteText(string content, bool append = true)  


_三皮_ 2011-02-25
  • 打赏
  • 举报
回复
学习,写日志也高效
qldsrx 2011-02-25
  • 打赏
  • 举报
回复
是不是高性能我不知道,我只看出了很多封装,按理说封装只是让用的简单,效率会降低些。
如果你是要追求性能,请使用内存映像文件来处理,估计5万并发量都可以支持。
problc 2011-02-25
  • 打赏
  • 举报
回复
学习一下,日志写好也不容易
yalan 2011-02-25
  • 打赏
  • 举报
回复
好文章!正在学这方面的东西,太有参考价值了!下载收藏了!谢谢!
ruanwei1987 2011-02-25
  • 打赏
  • 举报
回复
。。。。好砖,抛出来的不错
agdfhgfdshfgh 2011-02-25
  • 打赏
  • 举报
回复
看见咧,看见咧,小青年写的不孬,须青须青的小青年
porschev 2011-02-25
  • 打赏
  • 举报
回复

我去看一看。。。。暂时手上没有砖。。。

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧