Socket.Send + Async & Await: свой асинхронный метод отправки данных - C#

Узнай цену своей работы

Формулировка задачи:

Привет. Хочу написать свой асинх. метод для отправки данных при помощи класса Socket и его метода Send. Работать должно так. Есть некий метод, в котором вызывается
socket.SendTaskAsync(byte[] data);
После этого должна начатся асинхронная отправка данных, то есть поток, в котором вызывался метод, не должен замораживатся после вызова этого метода, а должен выполнятся дальше. Раньше я писал такое при помощи Begin/End.Send и Callback метода, а терь хочу по моднявому, с использованием async & await. Сидел я над этим делом два дня целых, но так и не написал, то, что надо, в конце концов вообще запутался в своем коде, вот последняя версия
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();
        }
    }
}
В методе SendTaskAsync вы можете видеть слип на 1 сек, это я спецом запилил, чтобы было ясно, работает ли Send, как мне надо. но нифига, после запуска проги, она ждет 1 сек, а потом выдает сначала "20", а потом "after send". Помогите плз разобратся, что я делаю не так???

Решение задачи: «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();
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 3.8 из 5
Похожие ответы