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();
}
}
}