Aplikacja "nie odpowiada" podczas sciągania plików z serwera ftp

Aplikacja "nie odpowiada" podczas sciągania plików z serwera ftp
S2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Witam, Problem polega na tym że przy ok 10 tym pliku ściąganym przez GetFile() w foreach - u; pojawia sie komunikat na górnym pasku aplikacji (brak odpowiedzi) i pasek postępu sie zatrzymuje, z tym że aplikacja kontynuuje działanie normalnie (nawet task menager nie wykazuje wzmożonego zużycia pracy procesora), ściąga do końca pliki i potem zwraca kontrole, Jak temu zapobiec?

Kopiuj
 
foreach (FtpItem file in file_list)
      {
         if (file.ItemType == FtpItemType.File)
          {
             try
                {
                 ftp.GetFile(file.Name, FilePathFull,FileAction.Create);
                }
              catch (Exception exep)
                {
                 MessageBox.Show(exep.Message + "\n\r Remote server file name: " + file.Name + "\r\n Local file name: " + FilePathFull, "File Download Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                  {
                     break;
                  }
                 }
         }
       }
wasiu
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 1552
0

Odpal akcje w osobnym procesie. To zalatwi sprawe.
Bo to wyglada na klasyczne zamulenie glownego watku czasozerna akcją - tego sie nigdy nie robi.

msm
  • Rejestracja: dni
  • Ostatnio: dni
1

Nie widzę tej klasy na MSDN (to twoja klasa? Ew. z jakiejś biblioteki?) Ale często takie metody mają swoje odpowiedniki asynchroniczne - np. GetFileAsync czy coś takiego - sprawdź, to może Ci wiele uprościć.

S2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Korzystam z biblioteki udostępnionej na http://www.starksoft.com/ i rzeczywiście jest GetFileAsync() Ale nie bardzo wiem jak to ugryźć.
Bo ta funkcja pozwala uruchomić tylko jeden plik na raz i rozumie że potem muszę odczekać aż wyrzuci event GetFileAsyncComplited i tam uruchomić kolejny plik?
A co do osobnego procesu to też nie bardzo wiem jak by to miało wyglądać był bym wdzięczny za jakiś prosty przykład kodu?

wasiu
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 1552
0

Nie procesu tylko wątku. Jest duża różnica.

Po prostu poczytaj o wątkach i asynchronicznym wywoływaniu metod - bo to można powiedzieć cały 'dział' jest i jeden przykład Ci tego nie wytłumaczy do końca.
W Twoim przypadku jak najbardziej trzeba odpalić metode GetFileAsync() i tu masz dwie opcje - pobierać kilka plików jednocześnie (wtedy odpalasz to pare razy), lub też jeden po drugim - wtedy po skończeniu jednego tak jak mówisz w GetFileAsyncComplited, gdzie update'tujesz progress i odpalasz pobieranie kolejnego (musisz sobie jakąś koleje przygotować wpierw i później z niej zdejmować kolejne pliki).
Ja bym wybrał to drugą opcje, gdyż ładnie progress operacji można obsłużyć, a czas w obu przypadkach ściągnięcia plików będzie podobny. Dodatkowo w pierwszy serwer może odrzucić Ci żądanie, gdyż np umożliwia tylko jedno czy kilka połączeń naraz, a Ty możesz chcieć śćiągnąć więcej plików.
Pewnie de facto obecnie robisz to samo z tą różnicą, że blokujesz wątek gui na czas tej operacji.

S2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Ok, Wiec na ten moment pliki ściągają się asynchronicznie i nic sie nie zawiesza, ale GetFileAsync() używa BackgroundWorker() ja w programie głównym deklaruje klasę FtpClient po czym uruchamiam połączenie i deklaruje eventy z tej klasy takie jak ServerRespond i TransferProgress i następnie uruchamiam pobieranie asynchroniczne i kończę procedurę. Po zakończeniu ściągania czyszcze eventy.
Problem polega na tym że w procedurach obsługi eventów nie może być żadnych kontrolek głównego okna ponieważ wyrzuca Exception o komunikacju między wątkami. Czytałem coś o komunikacji wątków ale nie bardzo umie się przez to przegryźć. Możecie mi jakiejś podpowiedzi udzielić albo jak ominąć ten problem w prosty sposób?

wasiu
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 1552
0

Aby wykonac operacje na kontrolkach z gui musisz wykonywac je na watku gui - w tym celu najprosciej mowiac napisz metode, ktora robi dana operacje i zrob jej Invoke'a na wątku gui.

http://4programmers.net/Forum/C_i_.NET/174975-invoke_w_watkach

Tutaj jest troche informacji o tym, a wiecej wiecej znalazlem tutaj:
http://codeguru.pl/frmThread.aspx?id=456373

Zwroc uwage na czesc z Invoke i InvokeRequiered - to zalatwi sprawe :) W wielkim skrocie - taki if z InvokeRequiered wywolujacy Invoke na samym sobie zmieni kontekst watku na watek GUI i juz nie bedziesz mial tego problemu :P

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.