如何同步套接字服务器中的线程以写入文件
问题描述:
我在写一个套接字服务器,它接收许多客户端请求以写入文件。我有一个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);
}
}
答
这是一个经典的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);
}
}
答
在这种情况下,最好对文件进行序列化访问,并通过同步队列将所有写请求转发到单独的线程,这主要有两个原因:
- 从多个线程写入/读取机械磁盘上的单个文件不会产生任何性能优势(如果存在很多线程,您甚至会看到性能下降)。
- 您将避免很多同步问题,尤其是在使用预定义的同步队列之一(如ConcurrentQueue)时。
看看以前发布的这个问题。 http://stackoverflow.com/questions/3507770/write-to-a-file-from-multiple-threads-asynchronously-c-sharp – ABH 2012-03-29 14:15:07