Ganesh Agrawal
Ganesh Agrawal

Reputation: 41

Writing to same file concurrently delay

I am using a socket server program which works asynchronously. I need to write the incoming packets to a single file. There are hundreds of clients connected at a time and can write the file concurrently. Here is the code that writes the received packet to file...

static ManualResetEvent signal = new ManualResetEvent(false);
signal.WaitOne();
using (StreamWriter sw = new StreamWriter(path, true))
       sw.WriteLine(message);
signal.Set();

The problem is that it's slowing down the next data packet to be received.

Upvotes: 1

Views: 142

Answers (2)

Sinatr
Sinatr

Reputation: 21999

It's not clear how you receive data. If you do as I think, then simple run logging operation asynchronously (fixing your code):

// define this somewhere to lock access to "path" file
private readonly object _lock = new object();

Task.Run(() =>
    {
        lock(_lock)
        {
            using (StreamWriter sw = new StreamWriter(path, true))
                sw.WriteLine(message);
        }
    });

Upvotes: 0

spender
spender

Reputation: 120450

You need to decouple your reading and writing. You can do this by using queues.

Create a single thread-safe message queue (ConcurrentQueue springs to mind).

Clients push messages into the queue.

Have a single writer that pops messages from the queue and commits each message in turn to disk (concurrent file IO from multiple threads is usually a performance killer anyway).

Now, the only synchronisation you need is taken care of by the queue, so it nicely eliminates a potential source of deadlock/blocking, and both ends of the consumer/producer chain are able to work at top speed.

Alternatively, take a look at TPL DataFlow. It's built for these sorts of producer/consumer situations. It's a worthy investment of your time.

Upvotes: 4

Related Questions