如何同步套接字服务器中的线程以写入文件

时间:2012-03-29 14:09:56

标签: c# multithreading

我正在编写一个套接字服务器,它接收许多写入文件的客户端请求。我有一个arraylist来存储socketlisteners。在我运行客户端以发送最多25个请求之后,这导致套接字服务器存储25个socketlisteners并启动25个线程来接收数据并写入文件。运行后,我从服务器获得错误,它试图访问由另一个进程锁定的同一文件。我也得到空引用错误。那么,同步线程的最佳方法是什么,以便处理所有请求并将所有数据写入文件。

感谢任何帮助。谢谢。 -CR

string data = Encoding.ASCII.GetString(byteBuffer,0, size);

if (!File.Exists(filepath))
{
    using (StreamWriter sw = File.CreateText(filepath))
    {
        sw.WriteLine(data);  
    }
}
else
{
    using (StreamWriter sw = File.AppendText(filepath))
    {
        sw.WriteLine(data);
    }
}

2 个答案:

答案 0 :(得分:0)

这是一个经典的Producer Consumer problem,您可以通过实施Pipeline模式轻松解决此问题。

基本上所有线程都会写入相同的线程安全队列而不是文件。而且你还需要一个线程,它将从共享集合中逐个读取所有可用的请求并写入文件。

使用.NET 4.X很容易使用BlockingCollection类来实现,这是一个线程安全的集合。

// request queue represented by a single string
var requestsQueue = new BlockingCollection<string>(); 

请求处理逻辑(在多个线程中运行)基本上只是将请求添加到队列中:

requestsQueue.Add(request);

将请求转储到文件的线程/任务应以下列方式使用可用请求:

using (StreamWriter sw = File.CreateText(filepath))     
{         
    foreach (var request in requestsQueue.GetConsumingEnumerable())
    {
       sw.WriteLinerequest);
    }
}

答案 1 :(得分:0)

在这种情况下,最好序列化对文件的访问,并通过同步队列将所有写请求转发到单独的线程,原因有两个:

  1. 从多个线程写入/读取机械磁盘上​​的单个文件不会产生任何性能优势(如果有许多线程,您甚至会看到性能下降)。
  2. 您将避免许多同步问题,尤其是如果您使用预定义的同步队列之一ConcurrentQueue