Я практикуюсь с асинхронной структурой CTP, и в качестве упражнения я бы создал TCP-клиента, способного запрашивать сервер (используя произвольный протокол).Во всяком случае, я застрял на самой ранней стадии, потому что проблема с подключением.Либо я до сих пор не понял какой-то базовый момент, либо есть что-то странное.
Итак, вот асинхронный разъем:
public class TaskClient
{
public static Task<TcpClient> Connect(IPEndPoint endPoint)
{
//create a tcp client
var client = new TcpClient(AddressFamily.InterNetwork);
//define a function to return the client
Func<IAsyncResult, TcpClient> em = iar =>
{
var c = (TcpClient)iar.AsyncState;
c.EndConnect(iar);
return c;
};
//create a task to connect the end-point async
var t = Task<TcpClient>.Factory.FromAsync(
client.BeginConnect,
em,
endPoint.Address.ToString(),
endPoint.Port,
client);
return t;
}
}
Я имею в виду, чтобы вызывать эту функцию только один раз, затемвозвращение экземпляра TcpClient
для использования в любом последующем запросе (код здесь не показан).
Где-то в моей форме я вызываю приведенную выше функцию следующим образом:
//this method runs on the UI thread, so can't block
private void TryConnect()
{
//create the end-point
var ep = new IPEndPoint(
IPAddress.Parse("192.168.14.112"), //this is not reachable: correct!
1601);
var t = TaskClient
.Connect(ep)
.ContinueWith<TcpClient>(_ =>
{
//tell me what's up
if (_.IsFaulted)
Console.WriteLine(_.Exception);
else
Console.WriteLine(_.Result.Connected);
return _.Result;
})
.ContinueWith(_ => _.Result.Close());
Console.WriteLine("connection in progress...");
//wait for 2" then abort the connection
//Thread.Sleep(2000);
//t.Result.Client.Close();
}
Тестэто попытка подключиться к удаленному серверу, но он должен быть недоступен (ПК включен, но служба остановлена).
Когда я запускаю функцию TryConnect, она возвращает правильно "соединение в процессе ...", как только, затем отображает исключение, потому что удаленная конечная точка выключена.Отлично!
Проблема в том, что для возврата исключения требуется несколько секунд, и я хотел бы дать пользователю возможность отменить выполняемую операцию.Согласно спецификации MSDN о методе BeginConnect, если вы хотите прервать асинхронную операцию, просто вызовите Close на рабочем сокете.
Итак, я попытался добавить пару строк в конце (закомментировано каквыше), поэтому для имитации отмены пользователей через 2 секунды.Результат выглядит как зависание приложения (песочные часы).При остановке IDE она останавливается на самой последней строке t.Result.Client.Close()
.Тем не менее, после остановки IDE все закрывается нормально, без каких-либо исключений.
Я также пытался закрыть клиент напрямую как t.Result.Close()
, но это точно так же.
Это я,или что-то не работает в процессе подключения?
Заранее большое спасибо.