#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
. Я отредактирую ответ, чтобы проиллюстрировать…