У меня есть простое клиентское приложение, которое получает байт-буферы из сети с низкой пропускной способностью. Вот код:
private static readonly HashSet<int> _capturedThreadIds = new HashSet<int>();
private static void RunClient(Socket socket)
{
var e = new SocketAsyncEventArgs();
e.SetBuffer(new byte[10000], 0, 10000);
e.Completed += SocketAsyncEventsArgsCompleted;
Receive(socket, e);
}
private static void Receive(Socket socket, SocketAsyncEventArgs e)
{
var isAsynchronous = socket.ReceiveAsync(e);
if (!isAsynchronous)
SocketAsyncEventsArgsCompleted(socket, e);
}
private static void SocketAsyncEventsArgsCompleted(object sender, SocketAsyncEventArgs e)
{
if (e.LastOperation != SocketAsyncOperation.Receive || e.SocketError != SocketError.Success || e.BytesTransferred <= 0)
{
Console.WriteLine("Operation: {0}, Error: {1}, BytesTransferred: {2}", e.LastOperation, e.SocketError, e.BytesTransferred);
return;
}
var thread = Thread.CurrentThread;
if (_capturedThreadIds.Add(thread.ManagedThreadId))
Console.WriteLine("New thread, ManagedId: " + thread.ManagedThreadId + ", NativeId: " + GetCurrentThreadId());
//Console.WriteLine(e.BytesTransferred);
Receive((Socket)sender, e);
}
Поведение в потоке приложения довольно любопытно:
- Метод
SocketAsyncEventsArgsCompleted
часто запускается в новых потоках. Я бы ожидал, что через некоторое время новый поток не будет создан. Я бы ожидал, что потоки будут повторно использоваться из-за пула потоков (или пула потоков IOCP) и потому, что пропускная способность очень стабильная. - Количество потоков остается низким, но я вижу в проводнике процессов, что потоки часто создаются и уничтожаются. Аналогично, я бы не ожидал, что потоки будут созданы или уничтожены.
Можете ли вы объяснить поведение приложения?
Изменить: "Низкая" пропускная способность составляет 20 сообщений в секунду (примерно 200 КБ/с). Если я увеличиваю пропускную способность до более 1000 сообщений в секунду (50 Мбайт/с), поведение приложения не изменится.