使用TPL FromAsync实现套接字超时的异常处理

时间:2013-08-02 16:05:30

标签: c# exception .net-4.0 task-parallel-library

我正在开发一个应该可以配置连接尝试超时的应用程序。

如果您查看下面的代码,您将意识到我正在尝试:等待20毫秒(此刻它是硬编码的),如果可以建立连接,则调用onConnected回调操作真正;否则为false(例如,如果发生超时)

internal void Connect(Action<bool> onConnected)
{
    Func<AsyncCallback, object, IAsyncResult> beginConnect =
        (callback, s) =>
            {
                var asyncResult = _socket.BeginConnect(Endpoint, callback, s);
                var success = asyncResult.AsyncWaitHandle.WaitOne(20, true);
                if(!success) throw new TimeoutException("Connection timeout");
                return asyncResult;
            };

    var task = Task.Factory.FromAsync(beginConnect, _socket.EndConnect, this);
    task.ContinueWith(t => onConnected(true), TaskContinuationOptions.NotOnFaulted)
        .ContinueWith(t => onConnected(false), TaskContinuationOptions.OnlyOnFaulted);
    task.ContinueWith(t => onConnected(false), TaskContinuationOptions.OnlyOnFaulted);
}

问题是由于beginConnect函数中的超时异常,从不调用回调。我想我可以在Connect方法调用者中用tyr-catch语句包装调用,但是它可以有几个调用者,并且在每个调用者看起来都是错误的。

我如何实现我想要的目标?

1 个答案:

答案 0 :(得分:0)

我找到了实现我想要的方法:

internal void Connect(Action<bool> onConnected)
{
    Func<AsyncCallback, object, IAsyncResult> beginConnect =
        (callback, s) => 
            {
                var asyncResult = _socket.BeginConnect(Endpoint, callback, s);
                var success = asyncResult.AsyncWaitHandle.WaitOne(20, true);
                if(!success)
                {
                    onConnected(false);
                    return default(IAsyncResult);
                }
                return asyncResult;
            };

    var task = Task.Factory.FromAsync(beginConnect, _socket.EndConnect, this);
    task.ContinueWith(t => onConnected(true), TaskContinuationOptions.NotOnFaulted)
        .ContinueWith(t => onConnected(false), TaskContinuationOptions.OnlyOnFaulted);
    task.ContinueWith(t => onConnected(false), TaskContinuationOptions.OnlyOnFaulted);
}

重点是,在20ms之后,如果还没有连接,它会使用false调用回调并返回默认的IAsyncResult。