Socket.Send + Async & Await: свой асинхронный метод отправки данных - C#
Формулировка задачи:
Привет. Хочу написать свой асинх. метод для отправки данных при помощи класса Socket и его метода Send. Работать должно так. Есть некий метод, в котором вызывается После этого должна начатся асинхронная отправка данных, то есть поток, в котором вызывался метод, не должен замораживатся после вызова этого метода, а должен выполнятся дальше. Раньше я писал такое при помощи Begin/End.Send и Callback метода, а терь хочу по моднявому, с использованием async & await.
Сидел я над этим делом два дня целых, но так и не написал, то, что надо, в конце концов вообще запутался в своем коде, вот последняя версия
В методе SendTaskAsync вы можете видеть слип на 1 сек, это я спецом запилил, чтобы было ясно, работает ли Send, как мне надо. но нифига, после запуска проги, она ждет 1 сек, а потом выдает сначала "20", а потом "after send".
Помогите плз разобратся, что я делаю не так???
socket.SendTaskAsync(byte[] data);
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AsyncServer { class Program { class SuperSocket : Socket { public SuperSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) : base(addressFamily, socketType, protocolType) { } public async Task<int> SendTaskAsync(byte[] buff) { Thread.Sleep(1000); var t = await this.MySendAsync(buff); int i = (int) t; return i; } //*********************************** private Task<int> MySendAsync(byte[] buff) { var _builder = new AsyncTaskMethodBuilder<int>(); Action _moveNext = delegate { try { //int i = this.Send(buff); int i = 20; _builder.SetResult(i); } catch (Exception exception) { _builder.SetException(exception); } }; _moveNext(); return _builder.Task; } //*************************************** } class AsyncServer { private SuperSocket socket; private byte[] buffer; public AsyncServer(int port) { buffer = new byte[1024]; // Получаем информацию о локальном компьютере IPHostEntry localMachineInfo = Dns.GetHostEntry(Dns.GetHostName()); IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, port); // Создаем сокет, привязываем его к адресу // и начинаем прослушивание socket = new SuperSocket( myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Bind(myEndpoint); socket.Listen((int) SocketOptionName.MaxConnections); Send(); // не должен замораживать поток Console.WriteLine("after send"); // должно отображатся первым } public async Task Send() { int i = (int) await socket.SendTaskAsync(new byte[10]); Console.WriteLine(i); } } static void Main(string[] args) { AsyncServer server = new AsyncServer(9095); Console.Read(); } } }
Решение задачи: «Socket.Send + Async & Await: свой асинхронный метод отправки данных»
textual
Листинг программы
using System; using System.Diagnostics; using System.Net; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication8 { class Program { async static void AsyncVersion() { Stopwatch sw = Stopwatch.StartNew(); string url1 = "http://rsdn.ru"; string url2 = "http://gotdotnet.ru"; string url3 = "http://blogs.msdn.com"; var webRequest1 = WebRequest.Create(url1); Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}", Thread.CurrentThread.ManagedThreadId); var webResponse1 = await webRequest1.GetResponseAsync(); Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1, webResponse1.ContentLength, sw.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId); var webRequest2 = WebRequest.Create(url2); Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}", Thread.CurrentThread.ManagedThreadId); var webResponse2 = await webRequest2.GetResponseAsync(); Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2, webResponse2.ContentLength, sw.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId); var webRequest3 = WebRequest.Create(url3); Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}", Thread.CurrentThread.ManagedThreadId); var webResponse3 = await webRequest3.GetResponseAsync(); Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3, webResponse3.ContentLength, sw.ElapsedMilliseconds, Thread.CurrentThread.ManagedThreadId); } static void Main(string[] args) { try { Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId); Task task = new Task(AsyncVersion); task.Start(); Console.WriteLine("Right after AsyncVersion() method call"); //Ожидаем завершения асинхронной операции task.Wait(); Console.WriteLine("Asyncronous task finished!"); } catch (System.AggregateException e) { //Все исключения в TPL пробрасываются обернутые в AggregateException Console.WriteLine("AggregateException: {0}", e.InnerException.Message); } Console.ReadLine(); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д