[С#] Добавление в ListBox строки из потока

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by bad_boy, 17 Oct 2010.

  1. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    На форме имеется компонент ListBox. В процессе работы необходимо его заполнять данными из потока.
    Схема работы такая: основной поток порождает BackgroundWorker(назовём поток А), который, в свою очередь, порождает ещё 10 BackgroundWorker'ов(потоки Б).
    Поток А передаёт в потоки Б параметры и запускает их на выполнение. Каждый поток Б, выполнившись, хранит результат в переменной result.
    Поток А проверяет эту переменную и должен записать её в ListBox.
    В отладчике я вижу, что переменная result содержит строку, но после выполнения
    mylist.Items.Add(mythreads[k].result);
    добавляется пустая строка.
    Каким образом исправить сие?
     
  2. interpUten

    interpUten New Member

    Joined:
    28 Sep 2010
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Судя по всему, никаких действий по синхронизации потоков нет? Конечно результат может быть не определен.
     
  3. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Нет. Но зачем она нужна в данном случае?!
    Потоки Б - классы. Каждый экземпляр хранит свой результат. :confused:
    Даже если ставить не 10,а 1 поток и в отладчике видно, что строка есть, она не добавляется. Как будто GC раньше времени стирает экземпляр.
     
    #3 bad_boy, 17 Oct 2010
    Last edited: 17 Oct 2010
  4. interpUten

    interpUten New Member

    Joined:
    28 Sep 2010
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Тогда я ничего не пойму - зачем использовать множества потоков, если нет конкуренции за ресурс(ListBox)? Это один из признаков что от применения потоков можно обойтись.
    И как поток А узнает что какой то из потоков окончил задания - опрашивает их или как кто изврашено вешается на event RunWorkerCompletedEventHandler. Покажи код.
     
    #4 interpUten, 17 Oct 2010
    Last edited: 17 Oct 2010
  5. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Множество потому, что брутфорс ;)
    Поток А - для того,чтобы приложение не висело и результат был виден в реальном времени.
    Да, опрашивает. Умнее придумать не смог.
    Code:
    for (int k = 0; k < mythreads.Length; )
    {
                        if (mythreads[k].Completed == true)
                        {
                            if (mythreads[k].result.Length > 0)
                            {
                                mylist.Items.Add(mythreads[k].result);
                            }
                            mythreads[k].Start(n);
                            break;
                        }
                        if (++k >= Bruts.Length) k = 0;
    }
    Алгоритм такой:
    1. Ищем завершённый поток.
    1.1 Если есть результат, то заносим в лист.
    1.2 Запускаем его с новым параметром(n).
    2. Циклимся пока не появится завершённый поток.
     
  6. interpUten

    interpUten New Member

    Joined:
    28 Sep 2010
    Messages:
    13
    Likes Received:
    1
    Reputations:
    0
    Да подход конечно не очень, а где именно в ListBox добавляешь - непосредственно в _DoWork методе потока А через delegate, или в .ReportProgress потока А. Если через .ReportProgress, вполне возможно что до того как туда что то уходит происходить Dispose потока В и ты не правильно заносишь, также если пишешь через Object userState нужно приводить к соответствующему типу.
     
    1 person likes this.
  7. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Да, в потоке А. Что такое delegate я ещё не знаю. Поясни, может в этом проблема.
     
  8. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    InvokeRequired -> BeginInvoke
    WorkerReportProgress = true -> RunWorkerCompleted
    profit
     
    1 person likes this.
  9. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    ну вот, а уже многопоточные приложения пишешь...
    была тема https://forum.antichat.ru/thread227512-delegate.html
     
    1 person likes this.
  10. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Всех благодарю, разобрался.

    BrainDeaD, уже писал, правда с C# работаю впервые.