2013-07-01 2 views
0

Просто с помощью .net сокетов в качестве примера, я использую:Что такое преимущества вызовов асинхронного метода?

TcpListener listener = new TcpListener(ip, port); 
while(true) 
{ 
    TcpClient client = socket.AcceptTcpClient(); 
    DoSomethingWithClient(client); 
} 

Но другой способ, кажется, что-то вроде (основано на http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.beginaccepttcpclient.aspx):

public static ManualResetEvent tcpClientConnected = new ManualResetEvent(false); 

public static void DoBeginAcceptTcpClient(TcpListener listener) 
{ 
    tcpClientConnected.Reset(); 
    listener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), listener); 
    tcpClientConnected.WaitOne(); 
} 

public static void DoAcceptTcpClientCallback(IAsyncResult ar) 
{ 
    TcpListener listener = (TcpListener) ar.AsyncState; 
    TcpClient client = listener.EndAcceptTcpClient(ar); 
    DoSomethingWithClient(client); 
    tcpClientConnected.Set(); 
} 

ИМХО стиль асинхронного требует 3 раза столько же кода и выглядит как goto spaghetti - его трудно читать и заставляет вас выделять связанный код. Так почему бы вам использовать асинхронный способ? Предположительно, это должно иметь какое-то преимущество?

+0

Асинхронные вызовы предотвращают блокировку потока во время ожидания ответа на вызов. –

+0

, если у вас длинный рабочий вызов (т. Е. 200 МБ BLOB), поток блокируется на такую ​​длительность, а при работе с асинхронным способом вы все равно можете продолжать работать и делать другие вызовы и запросы. – Marco

ответ

5

Он имеет то преимущество, что не блокирует поток звонящего, что особенно важно при создании интерактивных приложений, которые должны оставаться отзывчивыми даже при выполнении работы.

С C# 5 есть async/await, чтобы сделать этот код проще в написании и чтении.

0

Для большого количества одновременных клиентов использование асинхронных и синхронных методов позволяет приложению использовать меньшее количество потоков при выполнении одной и той же работы.

E.g. Я просто запускаю приложение, которое создает/управляет исходящими соединениями 2000, используя сначала около 30 потоков (меньше, поскольку потоки возвращаются в пул потоков).

Однако, как правило, немного сложнее запрограммировать этот путь и может быть немного скользким уклоном, так как вам придется сократить все источники заблокированных потоков, чтобы максимизировать преимущества.

Новый синтаксис уменьшает проблему кодовых спагетти и позволяет писать регулярные «неразрывные» методы, которые включают асинхронные вызовы.

Если вы не можете использовать синтаксис C# 5 и async/await, существуют другие способы, например, AsyncEnumerator от J. Richter.

1

Как уже упоминалось, асинхронный код позволяет использовать меньшее количество потоков и, таким образом, лучше масштабируется (для серверов) и остается отзывчивым (для клиентов пользовательского интерфейса).

Что касается сокетов TCP/IP, в частности, есть еще одна причина использовать асинхронные методы: вы можете писать и читать одновременно. Это необходимо в общем случае для предотвращения взаимоблокировок; все широкомасштабные универсальные серверы используют исключительно асинхронные сокеты.

Новый async/await в VS2012 обеспечивает гораздо более естественный способ написания асинхронного кода. Однако из-за того, что потоки чтения и записи являются независимыми, фактическое асинхронное программирование сокетов по-прежнему довольно сложное. У меня есть intro to async on my blog с некоторыми хорошими дополнительными ресурсами в конце.

Я считаю, что вы просто используете сокеты в качестве примера того, что может быть синхронным или асинхронным, но если вы действительно заинтересованы в использовании сокетов на этом уровне, вы также можете найти мой TCP/IP .NET Sockets FAQ.

Смежные вопросы