#c# #winforms
#c# #winforms
Вопрос:
Программа предназначена для подсчета слов в текстовых файлах. У меня есть две формы. Form1 касается выбора файлов и слов. Эти данные я передаю в form2, где я запускаю таймер графического интерфейса и алгоритм подсчета слов. Но алгоритм выполняется быстрее, чем загружается таймер GUI.
private void Form2_Load(object sender, EventArgs e)
{
CountWords();
}
Комментарии:
1. Начните здесь . «алгоритм выполняется быстрее, чем загружен таймер GUI» — неверно, таймер загружен и запущен в
InitializeComponents()
(в конструкторе формы), но он не может запускать свои события, потому чтоCountWords
блокирует поток пользовательского интерфейса.2. Я предлагаю использовать другой поток для вызова вашей функции countWords(). В этом потоке вызовите функции с помощью Invoke, чтобы обновить ваш графический интерфейс, если это необходимо. Если вам не нужна адаптивная форма во время преобразования, вызовите countWords в общедоступной функции после ее создания, а не в событии загрузки.
3. Почему вы открываете файл по таймеру? Меняется ли содержимое файла со временем, и вам нужно обновить пользовательский интерфейс новым содержимым? Если это так, смотрите также класс FileSystemWatcher . Этот класс вызывает различные события при изменении / удалении просматриваемого файла и т.д.
Ответ №1:
Вместо блокировки потока пользовательского интерфейса с помощью countWords запустите этот метод в фоновом потоке, используя Threadpool
private void Form2_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(
new WaitCallback(CountWords));
}
Затем убедитесь, что все вызовы элементов управления пользовательского интерфейса перенаправляются обратно в поток пользовательского интерфейса, который вы выполняете из фонового потока:
foreach (KeyValuePair<string, int> word in words)
{
// Need to marshal this back onto the UI thread
var itemToAdd = word.Key " " word.Value "x";
this.BeginInvoke(new Action<string>(AddItemToListView), itemToAdd);
}
И затем наш метод AddItemToListView добавит элемент в поток пользовательского интерфейса:
private void AddItemToListView(string item)
{
listView1.Items.Add(item);
}
Комментарии:
1. Упс, да, я хотел написать BeginInvoke. Спасибо.
2. Ошибка CS0123 Нет перегрузки для делегата совпадений ‘countWords’
3. Извините, вам нужно обновить свой метод countWords, чтобы он был private void countWords (параметр объекта)
4. Операция «От потока к потоку» недопустима: доступ к элементу управления ListView1 поступил из потока, отличного от потока, в котором он был создан. 🙁
5. В какой строке кода? Вы следили за моим кодом, потому что метод AddItemToListView() вызывается в потоке пользовательского интерфейса. Пожалуйста, обновите свой вопрос и опубликуйте весь свой исходный код.