Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Пауза в цикле / 9 сообщений из 9, страница 1 из 1
12.03.2014, 19:55
    #38584474
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
Всем доброго времени суток,

Не подскажите в чем может быть косяк, требуется элементарное: программа получает список файлов в папке и последовательно каждый файл загружает в SQL Server, при последовательной обработке каждого файла необходимо что бы контрол Label на форме принимал значение наименования файла который грузиться в данный момент.

Код метода собственно выглядит примерно так:


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
   Private Sub ProcessLoadXmlFilesFromCatalog(fpath As String)
        Dim lst() As String

        lst = Directory.GetFiles(fpath, "*.xml")

        For i = 0 To lst.Count - 1
            Label1.Text = "Обработка файла:" & lst(i)
            ListBox1.Items.Add("файл: " & lst(i))
            ProcessLoadXmlFile(lst(i))
            Thread.Sleep(2000)
        Next

    End Sub



импортированные пространства имен:
Imports System.Threading
Imports System.Data.SqlClient
Imports System.Xml
Imports System.IO


Проблема заключается в том, что когда вызывается данный метод, программа при наличии допустим 3 xml файлов в папке ждет 6 секунд, и потом разом выводит их в листбокс, т.е. последовательного появления в листбоксе через каждые 2 секунды файла нет.

С чем это может быть связанно, уже перелазил кучу тем, грешил на многопоточность, но я нигде явно в программе не создаю отдельных потоков
...
Рейтинг: 0 / 0
12.03.2014, 19:57
    #38584477
Pallaris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
связано с тем, что ты фактически вешаешь свой UI-поток на 6 секунд. Процесс нужно делать асинхронным и обновлять UI через Invoke
...
Рейтинг: 0 / 0
12.03.2014, 19:57
    #38584478
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
felix_ff,

с тем, что ваш код работает в потоке GUI, то есть пока он не выполнится, GUI не обновится. Загружать надо в отдельном потоке.

P.S. Делать задержки в цикле загрузки файлов это шедеврально
...
Рейтинг: 0 / 0
12.03.2014, 20:24
    #38584505
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
Pallaris,

Прошу прощения, смысл я понял но пока не знаю как это реализовать, не могли бы Вы подсказать как будет выглядеть это в виде кода или где про это можно прочесть?

Lelouch,

задержки в процессе загрузки файла потом не будет :)
Я написал паузы в цикле специально, для того что бы посмотреть что у меня происходит в процессе загрузки, потому что когда я запускал процесс загрузки Label никак не реагировал на изменение загружаемого файла
...
Рейтинг: 0 / 0
12.03.2014, 20:28
    #38584509
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
написал вот так: (на сколько я понимаю видимо чушь, раз не работает)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
  Delegate Sub MyDelegate(ByVal input As String)

    Private Sub SetProcessedFile(ByVal fname As String)
        StateLabel.Text = "Обработка файла:" & fname
        Label1.Text = "Обработка файла:" & fname
        ListBox1.Items.Add("файл: " & fname)
    End Sub

    Private Sub ProcessLoadXmlFilesFromCatalogEx(fpath As String)
        Dim lst() As String
        Dim d As New MyDelegate(AddressOf SetProcessedFile)

        lst = Directory.GetFiles(fpath, "*.xml")

        For i = 0 To lst.Count - 1
            d.Invoke(lst(i))
            Thread.Sleep(2000)
        Next

    End Sub

    Private Sub ProcessLoadXmlFilesFromCatalog(fpath As String)
        Dim thr As New Thread(AddressOf ProcessLoadXmlFilesFromCatalogEx)
        thr.Start(fpath)
    End Sub



выдает исключение что я пытаюсь изменить объект созданный в другом потоке,
я так понимаю что мне надо как то получить основной поток программы и вызвать SetProcessedFile в нем, но как правильно сделать?
...
Рейтинг: 0 / 0
12.03.2014, 20:33
    #38584515
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
felix_ff,

Pallaris имел в виду этот Invoke:

http://msdn.microsoft.com/ru-ru/library/zyzhdc6b(v=vs.110).aspx
Он есть в том числе и у формы
...
Рейтинг: 0 / 0
12.03.2014, 21:19
    #38584539
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
Lelouch, Pallaris,

Большое спасибо за помощь
...
Рейтинг: 0 / 0
13.03.2014, 09:21
    #38584731
Кифирчик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
felix_ff...надо как то получить основной поток программы и вызвать SetProcessedFile в нем...
1. Invoke нужно использовать там где есть доступ к визуальным контролам.
Invoke предполагает, что код который вы ему подсунули будет выполнен в обработчике потока который создал эту форму (у которой или компонента которой вызвали Invoke).
То есть, если вы ему всю функцию SetProcessedFile засунете, то это не будет отличаться от варианта без использования потока, и получатся те же задержки.
ИМХО, правильно, сделать подобное в отдельном потоке, например backgroundWorker-е либо Task, а куски которые пишут в визуальный контрол, обернуть в Invoke.
2. вместо Thread.Sleep() для прорисовки интерфейса мне видится лучше использовать Application.DoEvents();
в шарпе это бы выглядело примерно так
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        for(int i = 0; i < lst.Count - 1 ; i++)
        {
            this.Invoke(new Action(()=>{
              Label1.Text = "Обработка файла:" + lst[i];
              ListBox1.Items.Add("файл: " + lst[i]);
            }));
            Application.DoEvents();
            ProcessLoadXmlFile(lst[i]);
            
        }
...
Рейтинг: 0 / 0
13.03.2014, 19:45
    #38585656
igr_ok
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Пауза в цикле
felix_ff,

Попробуйте после
Label1.Text = "Обработка файла:" & lst(i)
написать
Label1.Refresh() или this.Refresh()
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Пауза в цикле / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]