Обычно неблокирующий ввод-вывод не обязательно дает лучшую производительность, но лучшую масштабируемость. Неблокирующая розетка ввода / вывода предотвращает необходимость в потоке для каждого соединения. Обслуживание многих соединений в одном потоке уменьшает затраты памяти и переключение контекста в нескольких потоках. Поскольку операции nio связаны с вводом-выводом, а не с процессором, я подозреваю, но не имею доказательств того, что любые издержки, вносимые ivkm, незначительны.
твуют ли какие-либо неблокирующие инфраструктуры ввода-вывода для .NET?
Я ищу что-то похожее на то, чтоАпач Мина а такжеJBoss Netty обеспечивает Java: среду для реализации хорошо масштабируемых серверов, а не только низкоуровневую поддержку, предоставляемую .NET Framework.
РЕДАКТИРОВАТЬ: Чтобы лучше объяснить, что я хотел бы увидеть, вот основной пример того, что вы можете сделать с Миной:
В Мине я могу реализовать ProtocolDecoder, как это:
public class SimpleDecoder extends CumulativeProtocolDecoder {
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (in.remaining() < 4)
return false;
int length = in.getInt();
if(in.remaining() < 4 + length)
return false;
Command command = new Command(in.asInputStream());
out.write(command);
}
}
И CommandHandler, как это:
public abstract class CommandHandler extends IoHandlerAdapter{
public void messageReceived(IoSession session, Object message) throws IOException, CloneNotSupportedException {
Command command = (Command) message;
// Handle command. Probably by putting it in a workqueue.
}
}
Если я запускаю сервер по телефону
CommandHandler handler = new CommandHandler();
NioSocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new SimpleDecoder(false)));
acceptor.setLocalAddress(new InetSocketAddress(port));
acceptor.setHandler(handler);
acceptor.bind();
Я получу неблокирующий сервер.
Он будет запускать один (или хотя бы несколько) потоков, циклически проходя по всем входящим соединениям, собирая данные из сокетов и вызываяSimpleDecoder.doDecode()
чтобы увидеть, если он имеет полную команду на соединение. Затем он передаст командуCommandHandler.messageReceived()
и я могу взять на себя обработку.