多线程写入单个文件
本文关键字:文件 单个 多线程 | 更新日期: 2023-09-27 18:15:30
我使用BlockingCollection
用于我的多线程目的。我要做的是:
-
删除一些数据
-
导出数据到1个文件
#1可以正常工作,但是当我到达#2时,文件最终重叠,所以我的文件最终是这样的(这是一个示例,确切的输出顺序不同):
|col 1|col 2|col 1|col 3|col 2|col 1|
而不是像这样:
|col 1|col 2|col 3|
|col 1|col 2|col 3|
显然我有线程重叠的问题,但我不知道如何解决这个问题?这个问题已经被问到,提出的解决方案是使用lock
,我确实尝试过,,但它不起作用。编辑:使用锁工作-我在我的代码中有另一个问题- "exportString"变量是全局的,所以相同的变量在所有线程之间共享。
下面是导出代码(由每个线程调用):
class ExportClass{
private Object locker = new Object();
public void Report(string exportString, string fileLoc){
lock (locker)
{
File.AppendAllText(fileLoc + "''data.csv", exportString + "'n");
}
}
}
这是我的BlockingCollection
代码:
class Multithreading
{
BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public Multithreading(int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
Task.Factory.StartNew(Consume);
}
public void Dispose() { _taskQ.CompleteAdding(); }
public void EnqueueTask(Action action) { _taskQ.Add(action); }
void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
foreach (Action action in _taskQ.GetConsumingEnumerable())
action(); // Perform task.
}
}
您的locker
对象需要是静态的,否则ExportClass的多个实例将有它们自己的锁对象,这完全违背了锁语句的目的。
但是,老实说,答案不是你想要的。答案是首先执行多线程工作,将结果存储在内存中,然后在单个线程中输出结果。如果您尝试从多个线程执行对同一文件的写操作,并且使用锁定语义,那么您实际上会比这慢得多。
使储物柜静态
class ExportClass{
private static Object locker = new Object();
public void Report(string exportString, string fileLoc){
lock (locker)
{
File.AppendAllText(fileLoc + "''data.csv", exportString + "'n");
}
}
}
就像十二面体说的比我早2秒