0

I have a problem, I have my main class with gui, second class (FTP) that operates FTP, third class (ServerClass) that collect all information about (username, pass, address, time etc.) and fourth class (ManagingClass) that operates them all (it uses dictionary to store them).

When user click add, main class first checks if it can connect to server and only then it adds it to dictionary. It sends all info to method from ManagingClass that checks connection and returns bool by sending it to method from another class - FTP. It worked fine.

But because checking connection is time consuming and while it checks gui was not responsive (and in the future when it would download large files - gui would be not responsive for a long time) I decided to add progressBar so it would show progress. I started reading about BackgroundWorker and BeginInvoke (report progress backgroundworker from different class c# , How can we show progress bar with FtpWebRequest etc.) but i have a problem: I need it to work over two classes - Form -> ManagingClass -> FTP, return true or false AND send progressupdate.

FTP method:

    public bool checkConnection()
    {
        try
        {
            ftpRequest = (FtpWebRequest)WebRequest.Create(@"ftp://" + host);
            OnProgressUpdate(25);
            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
            OnProgressUpdate(50);
            ftpRequest.Credentials = new NetworkCredential(user, password);
            OnProgressUpdate(75);
            ftpRequest.GetResponse();
            OnProgressUpdate(100);


        }
        catch
        {
            return false;
        }
        return true;

    }

In ManagingClass

    public bool checkConnection(string serverAddress)
    {
         checkingBackgroundWorker.RunWorkerAsync(serverAddress);
         return Result;

    }

    private void checkingBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        string serverAddress = e.Argument as string;
        ServerClass server;
        serverDictionary.TryGetValue(adresSerwera, out server);
        FTP whatever = new FTP(server);
        whatever.OnProgressUpdate += whatever_OnProgressUpdate;


        e.Result = whatever.checkConnection();

    }

    private void checkingBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Result = (bool)e.Result;
    }

And in my Form:

            string[] temp = AllToStringa();
            managingClass.AddFromForm(temp);

            if (!managingClass.checkConnection(temp[0]))
            { ...

    private void managingClass_OnProgressUpdate(int value)
    {
        base.Invoke((Action)delegate
        {
            progressBarDownload.Value = value;
        });
    }

First of all - isn't there some better way of doing it?;p It somehow seems unintuitive

And second - unfortunately in my managing class when i do RunWorkerAsync it seems to create new instance of ManagingClass without copying objects so serverDictionary.TryGetValue returns exception because serverDictionary = null (while it is created in constructor). In theory i could just send each time all information needed by eventargs but it somehow seems dirty;p but if there is no other way..

Community
  • 1
  • 1
Pumar
  • 91
  • 2
  • 13
  • When you translate before posting then test (compile) it tomake sure it's correct or don't do it at all. – H H Jul 30 '13 at 08:51
  • Your `return Result;` can never work, you don't need to `Invoke()` in `OnProgressUpdate()` and `TryGetValue(adresSerwera, ...)` is not thread-safe. But none of this explains what you see. – H H Jul 30 '13 at 08:55

1 Answers1

0

Yes, a better way of creating asynchronous programs is Async and Await. Please refer the following link for more details: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

Palak.Maheria
  • 1,497
  • 2
  • 15
  • 32