Список файлов с FTP в ListView с использованием фонового рабочего в C#

#c# #listview #ftp #backgroundworker

#c# #просмотр списка #ftp #фоновый рабочий

Вопрос:

Я работаю над приложением, которое проверит ftp-сервер и перечислит все файлы каталога, которые отлично работают без ФОНОВОГО РАБОЧЕГО, но когда я использую фоновый рабочий, возникает много проблем. Первая проблема заключалась в том, что я не могу получить доступ к ListView из фонового рабочего, я использовал другой метод (сохранить список в массиве, а затем обновить по завершении фонового рабочего процесса), но это не сработало. Затем я использовал другую форму, которая была скрыта и выполняла ту же функцию, но программа все еще зависала при перечислении файлов FTP. На самом деле, я просто хочу перечислить файлы этого каталога (ftp://blah/subdir /[файлы находятся здесь]) в ListView1. Как это возможно без замораживания пользовательского интерфейса? я пытался использовать Background worker, но это не сработало, как его использовать для работы? Вот код

функция

 public string[] ListDirectory()
    {
        string hostdir = textBoxX2.Text   textBoxX3.Text;
        var request = createRequest(hostdir,WebRequestMethods.Ftp.ListDirectory);
        using (var response = (FtpWebResponse)request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(stream, true))
                {
                while (!reader.EndOfStream)
                {
                 listView1.Items.Add(reader.ReadLine());
                }
            }   
         }
      }
        List<string> l = new List<string>();
        return l.ToArray();
}
private FtpWebRequest createRequest(string uri, string method)
    {
        var r = (FtpWebRequest)WebRequest.Create(uri);
        r.Credentials = new NetworkCredential(textBoxX4.Text, textBoxX5.Text);
        r.Method = method;
        return r;
    }
  

Приведенный выше код работает, но зависает пользовательский интерфейс, и когда я использую background worker, некоторые функции не работают, например, не могут получить доступ к ListView1 из объекта, на котором он был создан, или что-то подобное.

Приветствуется любая помощь… Спасибо

Ответ №1:

Вы могли бы попробовать этот подход — Invoke запускает действие в соответствующем потоке:

 string line = reader.ReadLine();
listView1.Invoke((MethodInvoker)delegate {
    listView1.Items.Add(line); // runs on UI thread
});
  

В вашем случае вы знаете, что находитесь не в потоке пользовательского интерфейса, но если у вас есть функция, которая может быть вызвана либо из потока пользовательского интерфейса, либо из рабочего потока, вам нужно проверить InvokeRequired :

 string line = reader.ReadLine();
if ( listView1.InvokeRequired ) {
    listView1.Invoke((MethodInvoker)delegate {
        listView1.Items.Add(line); // runs on UI thread
    });
}
else {
    // we're already on UI thread - work on ListView1 directly
    listView1.Items.Add(line);
}
  

Комментарии:

1. Большое вам спасибо, это сработало идеально, но как насчет . и .. ?

2. Как я могу удалить. и .. [ТОЧКИ]

3. Я не знаком с форматом строки, которую возвращает этот FTP-запрос, но если вы можете определить, где находится имя каталога, вы могли бы проверить, что это не . или .. .

4. хм, да, я могу это сделать. Большое спасибо за вашу помощь. я застрял в этой проблеме на 3 дня.

5. Не беспокойтесь! Если у вас есть функция, которая может вызываться либо из потока пользовательского интерфейса, либо из рабочего потока, вам также необходимо проверить ListView1.InvokeRequired . Это флаг, который сообщает вам, нужно ли использовать Invoke . Я отредактирую ответ, чтобы проиллюстрировать…