I'm using Rebex FTP library (plain old FTP, no security needed). I'm working asynchronously, in a multi-threaded environment, so the code in my class looks pretty much like this:

public class MyDownloader : IDisposable
{
    private readonly Ftp ftp = new Ftp();
    private MemoryStream ms = new MemoryStream();

    public void Download()
    {
        // connect, login, etc.            
        object state = null;
        ftp.BeginGetFile("remote/path", ms, MyCallback, state);
    }

    private void MyCallback(IAsyncResult ar)
    {
        try
        {
            var size = ftp.EndGetFile(ar);
        }
        catch
        {
            // log, whatever
        }

    }

    public void Dispose()
    {
        // disconnect if needed
        ftp.Dispose();
    }
}

The Questions

Let's say that there's a so-called race between 2 threads: Thread A calls the Dispose method in my class, and Thread B invokes the callback method (MyCallback) on the same time.

  1. Should I write my own mechanism for checking the state of my class (disposed or not)?
  2. Is it possible that after calling FTP's Dispose method, my class' MyCallback method will be executed at all?

Thanks!

asked 21 Apr '11, 09:54

Ron%20Klein's gravatar image

Ron Klein
273
accept rate: 0%

edited 21 Apr '11, 13:37


To 1.) If the Ftp object was disposed before finishing the BeginXXX method, an FtpException is thrown when calling the EndXXX method. If the Ftp object was disposed after finishing the BeginXXX method, call of the EndXXX method will succeed without an exception. I suggest you to add the following catch to handle ObjectDisposedException in this case:

catch (FtpException ex)
{
    if (ex.Status == FtpExceptionStatus.AsyncError && ex.InnerException != null && ex.InnerException is ObjectDisposedException)
        // handle background ObjectDisposedException
}

To 2.) Ones the BeginXXX method was successfully called, the callback method will be executed always (even the object has been already disposed). If an exception occurred during the background operation, calling the EndXXX method will throw an FtpException with the FtpExceptionStatus.AsyncError.

link

answered 21 Apr '11, 12:50

Lukas%20Matyska's gravatar image

Lukas Matyska ♦♦
90117
accept rate: 28%

edited 21 Apr '11, 13:35

I understand your answer, but it raises another question: Regarding the BeginGetFile method of the Ftp class - is it thread-safe? I mean, if two different threads invoke BeginGetFile and Dispose methods - is there a race?

(21 Apr '11, 13:09) Ron Klein

The whole Ftp class is thread safe. Let suppose 3 cases:

  1. thread A invokes BeginGetFile, then thread B invokes Dispose (in next instruction). Result: no data are transferred and a callback is executed. Calling the EndGetFile method throws an FtpException as described in the previous answer.
  2. thread B invokes Dispose, then thread A invokes BeginGetFile (in next instruction). Result: calling the BeginGetFile method in thread A throws an ObjectDisposedException.
  3. thread A invokes BeginGetFile, then thread B also invokes BeginGetFile. Result: calling the BeginGetFile method in thread B throws an FtpException with the FtpExceptionStatus.Pending. Thread A will continue and data will be transferred.
link

answered 21 Apr '11, 13:33

Lukas%20Matyska's gravatar image

Lukas Matyska ♦♦
90117
accept rate: 28%

Thanks! :-)

(21 Apr '11, 13:35) Ron Klein
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×152
×9

Asked: 21 Apr '11, 09:54

Seen: 855 times

Last updated: 21 Apr '11, 13:37