Jef*_*ron 37 c# io file-io multithreading asynchronous
这是我的情况.我想在我的应用程序中尽可能高效地写入文件系统.该应用程序是多线程的,每个线程都可以写入同一个文件.有没有一种方法可以从每个线程异步写入文件,而不会让不同线程中的写入结合在一起,可以这么说?
我正在使用C#和.NET 3.5,我也安装了Reactive Extensions.
µBi*_*Bio 14
看看异步I/O.这将释放cpu以继续执行其他任务.
与ReaderWriterLock结合为@Jack B Nimble提到
If by
尽可能高效地写入文件系统
你的意思是尽可能快地制作实际的文件I/O,你将很难加快速度,磁盘只是速度慢.SSD也许?
Mat*_*ius 12
对于那些喜欢代码的人,我使用以下来从Web应用程序进行远程日志记录...
public static class LoggingExtensions
{
static ReaderWriterLock locker = new ReaderWriterLock();
public static void WriteDebug(this string text)
{
try
{
locker.AcquireWriterLock(int.MaxValue); //You might wanna change timeout value
System.IO.File.AppendAllLines(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\", ""), "debug.txt"), new[] { text });
}
finally
{
locker.ReleaseWriterLock();
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这能为您节省一些时间
我要做的是有单独的工作线程专门用于编写文件的任务.当你的其他一个线程需要写出一些数据时,它应该调用一个函数来将数据添加到ArrayList(或其他一些容器/类).在这个函数中,顶部应该有一个lock语句,以防止同时执行多个线程.在添加对ArrayList的引用之后,它返回并继续其杂务.有几种方法可以处理写入线程.可能最简单的是简单地将它放入一个带有睡眠语句的无限循环中,这样它就不会咀嚼你的cpu.另一种方法是使用线程原语,并在没有更多数据要写出时进入等待状态.此方法意味着您必须使用类似ManualResetEvent.Set方法的方法激活线程.
有许多不同的方法可以在.NET中读入和写出文件.我写了一个基准程序并在我的博客中给出结果:
http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp
如果您需要性能,我建议使用Windows ReadFile和WriteFile方法.避免使用任何异步方法,因为我的基准测试结果表明使用同步I/O方法可以获得更好的性能.
Bob Bryan MCSD
虽然基于线程的锁可以解决这个问题,但是有一种方法可以跨线程工作,但是当你有多个进程写入单个文件的末尾时,最好使用它.
要在进程(或线程)之间获得此行为,请指定在创建OS文件句柄时希望对操作系统进行原子追加写入.这是通过在Posix(Linux,Unix)下指定O_APPEND和在Windows下指定FILE_APPEND_DATA来完成的.
在C#中,您不直接调用操作系统'open'或'CreateFile'系统调用,但有多种方法可以获得此结果.
我问过一段时间以前在Windows下如何做到这一点,并在这里得到了两个好的答案:如何在C#中进行原子写/附加,或者如何使用FILE_APPEND_DATA标志打开文件?
基本上,您可以使用FileStream()或PInvoke,我建议使用PInvoke上的FileStream(),原因很明显.
您可以使用参数的构造函数对FILESTREAM()来指定我异步文件/除了FileSystemRights.AppendData标志,它应该给你两个异步I/O和原子追加写入文件O操作.
警告:某些操作系统对可以原子方式写入的最大字节数有限制,超过该阈值将删除操作系统的原子性承诺.
由于这个最后的问题,我建议在尝试在单个进程中解决您的问题时保持lock()样式争用管理.
| 归档时间: |
|
| 查看次数: |
63682 次 |
| 最近记录: |