Implement Aysnc with timeout

0 votes
asked Sep 8, 2011 by mbell8903 (120 points)
edited Sep 9, 2011

I am trying to implement an async FTP client and a tried the following. It seems to work well with the exception of FTPS connections. As I was revieing my issue with FTPS i found the Rebex.Net.FtpOptions.TimeoutAsynchronousMethods enum. How does this work? What happens when the async method times out? How can i handle the timeout? Also If i want multiple options can i just bitwise & them together like the following:

// Set client options

client.Options = Rebex.Net.FtpOptions.TimeoutAsynchronousMethods & Rebex.Net.FtpOptions.KeepAliveDuringTransfer & Rebex.Net.FtpOptions.UseLargeBuffers & Rebex.Net.FtpOptions.DisableProgressPercentage;

// Old code mentioned above

public void Connect()
{
    IAsyncResult asyncResult = null;

    try
    {
        if(log != null)
            log.DebugFormat("TaskId: {0} | Openning a FTP connection to server '{1}:{2}'", taskId, this.ServerIP, this.Port);

        asyncResult = client.BeginConnect(this.ServerIP, this.Port, new AsyncCallback(Connected), null);

        if (log != null)
            log.DebugFormat("TaskId: {0} | Waiting for the FTP connection to open", taskId);

        asyncResult.AsyncWaitHandle.WaitOne(timeout, true);

        if (!asyncResult.IsCompleted)
            throw new Rebex.Net.FtpException("A timeout occured while attempting to open a FTP connection to the server", Rebex.Net.FtpExceptionStatus.Timeout);
    }
    finally
    {
        client.EndConnect(asyncResult);

        if (asyncResult != null)
             asyncResult.AsyncWaitHandle.Close();

        asyncResult = null;
    }
}

private void Connected(IAsyncResult asyncResult)
{
    if (log != null)
        log.DebugFormat("TaskId: {0} | Successfully opened the FTP connection", taskId);
}
Applies to: Rebex FTP/SSL

1 Answer

0 votes
answered Sep 9, 2011 by Lukas Pokorny (112,470 points)
edited Sep 9, 2011

By default, asynchronous operations started by methods (such as BeginConnect or BeginPutFile) never time out and the value of Ftp object's Timeout property doesn't affect them. But when the TimeoutAsynchronousMethods option is enabled, they time out just like synchronous methods (such as Connect or PutFile).

When an asynchronous method times out, an FtpException with Status of FtpExceptionStatus.Timeout is thrown. This is similar to other kind of errors. The asynchronous operations ends immediately, which means the callback gets called. The exception is thrown as soon as you can the End* method (such as EndConnect or EndPutFile).

Please note that the Timeout value doesn't specify the maximum time allowed for the whole operation. Instead, the operation times out when no response has been received for the specified amount of time.


You can specify multiple options, but you have to use bitwise | instead of &:

// Set client options
client.Options = Rebex.Net.FtpOptions.TimeoutAsynchronousMethods |
    Rebex.Net.FtpOptions.KeepAliveDuringTransfer |
    Rebex.Net.FtpOptions.UseLargeBuffers |
    Rebex.Net.FtpOptions.DisableProgressPercentage;

Using the & operator would be equivalent to client.Options = 0; and no flags would be set. For detailed explanation, check out this link.

...