gpt4 book ai didi

c# - 在后台写入文件

转载 作者:太空狗 更新时间:2023-10-29 23:58:10 24 4
gpt4 key购买 nike

给定一个写入文本文件的方法

public void WriteToFile( ) {
var file = "C:\\AsyncTest.txt";
var writer = File.Exists( file ) ? File.AppendText( file ) : File.CreateText( file );
writer.WriteLine( "A simulated entry" );
writer.Close();
}

我需要模拟一个场景,在这个场景中这个方法可以在循环中调用,可能会调用几十次并且必须异步运行。

所以我尝试像这样在一个新线程中调用该方法(writer 是 WriteToFile 所在的类)

//in a loop...
Thread thread = new Thread( writer.WriteToFile );
thread.Start( );

一次完美运行,但抛出一个 IO 异常,表明该文件在后续迭代中被另一个进程使用。实际上,这非常有道理,但我不知道如何解决它。

我试过像这样使用 Join()

Thread thread = new Thread( writer.WriteToFile );
thread.Start( );
thread.Join();

但这会锁定调用线程,直到所有加入的线程完成,这有点违背了目的,不是吗?

我尝试使用 ThreadPool.QueueUserWorkItem(writer.WriteToFile);,但得到相同的 IO 异常。

我试过用锁

private object locker = new object();

public void WriteToFile( ) {
lock(locker){
//same code as above
}
}

但这并没有明显的效果

我也尝试过使用 Task 类,但无济于事。

那么我怎样才能“堆叠”这些后台线程以在不发生冲突的情况下写入单个文件,同时又不锁定调用线程?

最佳答案

另一种选择是创建队列。让主线程将字符串放在队列中,并让持久的后台线程读取队列并写入文件。这真的很容易做到。

private BlockingCollection<string> OutputQueue = new BlockingCollection<string>();

void SomeMethod()
{
var outputTask = Task.Factory.StartNew(() => WriteOutput(outputFilename),
TaskCreationOptions.LongRunning);

OutputQueue.Add("A simulated entry");
OutputQueue.Add("more stuff");

// when the program is done,
// set the queue as complete so the task can exit
OutputQueue.CompleteAdding();

// and wait for the task to finish
outputTask.Wait();
}

void WriteOutput(string fname)
{
using (var strm = File.AppendText(filename))
{
foreach (var s in OutputQueue.GetConsumingEnumerable())
{
strm.WriteLine(s);
// if you want to make sure it's written to disk immediately,
// call Flush. This will slow performance, however.
strm.Flush();
}
}
}

后台线程在输出队列上进行非忙等待,因此它不会使用 CPU 资源,除非它实际输出数据。并且因为其他线程只需要将一些东西放到队列中,所以基本上没有等待。

查看我的博客,Simple Multithreading, Part 2了解更多信息。

关于c# - 在后台写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17994169/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com