多线程写入单个文件

本文关键字:文件 单个 多线程 | 更新日期: 2023-09-27 18:15:30

我使用BlockingCollection用于我的多线程目的。我要做的是:

  1. 删除一些数据

  2. 导出数据到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秒