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

问题描述:

我在写一个套接字服务器,它接收许多客户端请求以写入文件。我有一个arraylist来存储socketlisteners。在我运行客户端发送多达25个请求后,这会导致套接字服务器存储25个socketlistener并启动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); 
    } 
} 
+0

看看以前发布的这个问题。 http://*.com/questions/3507770/write-to-a-file-from-multiple-threads-asynchronously-c-sharp – ABH 2012-03-29 14:15:07

这是一个经典的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. 从多个线程写入/读取机械磁盘上​​的单个文件不会产生任何性能优势(如果存在很多线程,您甚至会看到性能下降)。
  2. 您将避免很多同步问题,尤其是在使用预定义的同步队列之一(如ConcurrentQueue)时。