2016-03-27 24 views
5

Tworzę aplikację typu Formularz systemu Windows, który dynamicznie tworzy formanty na podstawie danych pobranych z bazy danych.VB/C# .net Dynamicznie dodawanie elementów sterujących za pomocą pracownika tła

Mam kod działa świetnie w tle, który ładuje dane z bazy danych i stosuje go do zmiennych, problem, który mam jest, gdy próbuję utworzyć formanty przy użyciu tych danych, pojawia się błąd wielowątkowości (Dodatkowe informacje: operacja Cross wątek nie ważne. dostęp z wątku innego niż wątek został utworzony na)

Używam zdarzenie BackgroundWorker_DoWork i kod, który nie działa to kontrola „flowpanelMenuRules” następuje:

Me.flowpanelMenuRules.Controls.Add(PanelRule(i)) 

Powyższy kod to prosta pętla przechodząca przez zmienną (która jest pulle d z bazy danych) i zebranie informacji.

Czy ktoś miał jakiekolwiek doświadczenie w bezpiecznym przywoływaniu powyższej linii? Ja po prostu nie może wydawać się zmusić go do pracy na wszystkich :(

Dzięki za pomoc, w razie potrzeby mogę pisać więcej kodu.

+0

Zobacz https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-read-other-than-therq=1, aby uzyskać wyjaśnienia na temat poszło źle. –

+0

Kontrolki nie powinny być tworzone na wątku tła. Zostają przypisani do wątku, w którym są stworzeni i powinni być tam tylko wykorzystywani. Powinieneś powołać się na konkretne tworzenie i aktualizację kontrolek, reszta może być wykonana w BGW. –

Odpowiedz

6

Zalecam, aby Twój pracownik tła po prostu utworzył kontrolki, ale nie dodał ich do formularza. Zamiast tego, prześlij przygotowane formanty do wątku wywołującego/interfejsu użytkownika poprzez zdarzenie RunWorkerCompleted. Następnie dodaj formanty do formularza w tym miejscu, prawdopodobnie w połączeniu z metodami SuspendLayout()/ResumeLayout().

+1

Joel - Użyłem tego pomysłu i działa idealnie. Mam działającego w tle teraz, który uruchamia mój kod SQL, aby pobrać informacje z bazy danych do zmiennych, a następnie użyć zdarzenia wykonanego przez pracownika tła do zapełnienia wyników w FlowLayoutPanel. Dziękuję Ci! Użyłem wcześniej pracowników tła, ale z jakiegoś powodu wydarzenie Ukończono właśnie wymknęło mi się z głowy –

1

natywny sposób dla aplikacji WinForms jest użycie System.Winfows.Forms.Control metod jak i Invoke()InvokeRequired nieruchomość w dostępie do wątku UI:

if(this.flowpanelMenuRules.InvokeRequired) 
{ 
    this.flowpanelMenuRules.Invoke(() => AddPanelRule()); 
} 
else 
{ 
    AddPanelRule(); 
} 

można również użyć Dispatcher klasa

Jeżeli jesteś pewien, aby być w wątku UI (np procedury obsługi button.Click).udostępnia program do przesyłania wątków interfejsu użytkownika, który można później użyć do przesyłania z wątków działających w tle do wątku interfejsu użytkownika, jak zwykle.

Dispatcher.CurrentDispatcher.Invoke(() => this.flowpanelMenuRules.Controls.Add(PanelRule(i))); 
+0

Czy mieszałeś VB i C#? – Camo

+0

@Rinecamo pytanie zostało zadane z tagiem C#, a wszystkie moje przykłady zawierają tylko kod C#. –

+0

'Me' jest odpowiednikiem VB tego';) – Camo