Suggestions for asynchronous I / O with a parallel task library

I have a high-performance file transfer code that I wrote in C # using the asynchronous programming model (APM) idiom (e.g. BeginRead / EndRead ). This code reads the file from the local disk and writes it to the socket.

To ensure the best possible performance on modern equipment, it is important, if possible, to support more than one outstanding in-flight I / O operation. Thus, I send several BeginRead operations to the file, then when it completes, I call BeginSend on the socket, and when it completes, I do another BeginRead in the file. The details are a little more complicated, but at a high level this idea.

I have APM based code but it is very difficult to follow and probably has subtle concurrency errors. I would like to use TPL for this. I thought Task.Factory.FromAsync would just do it, but there is a trick.

All the I / O patterns I've seen (in particular the StreamExtensions class in Extensions Extensions Extensions) assume a single read followed by a single record. This will not work as I need.

I can’t use something simple like Parallel.ForEach or Extras Task.Factory.Iterate , because async I / O tasks do not spend much time on the workflow, so Parallel runs another task, which leads to a potential dozens or Hundreds of pending I / O too much! You can get around this with Wait on your tasks, but this causes the creation of an event descriptor (kernel object) and a lock wait on the task handle that binds the worker thread. My APM implementation excludes both of these things.

I play in many ways to keep several read / write operations in flight, and I managed to do this using continuations that invoke a method that creates another task, but it feels awkward and definitely doesn't feel like an idiomatic TPL.

Has anyone else dealt with a problem similar to this problem with TPL? Any suggestions?

+4
source share
1 answer

If you worry about too many threads, you can simply set ParallelOptions.MaxDegreeOfParallelism to an acceptable number in your call to Parallel.ForEach .

+2
source

Source: https://habr.com/ru/post/1309616/


All Articles