Edytowanie UI wykorzystując osobny wątek

Edytowanie UI wykorzystując osobny wątek
TR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1
0

Witam,
borykam się z pewnym problemem. Napisałem funkcję, która jest wywoływana przez nowy wątek z wykorzystaniem klasy BackgroundWorker. Funkcja działa nieprzerwanie.
Jej zadaniem jest utworzenie w Form1 PictureBox'a lub kilku PictureBox'ów, nic więcej. Oczywiście wywołując funkcję pojawia się błąd, że wątek ten nie ma uprawnień do edytowania UI.
Czytałem trochę nt. klasy Invoke, jednakże nie wiem jak ją zaimplementować, i to dla nieokreślonej liczby obiektów.
Szukam uniwersalnego rozwiązania, które pozwoliło by edytować Form1 z wykorzystaniem osobnego wątku.
Dziękuję za pomoc

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
1

wywołując funkcję pojawia się błąd

grammar nazi: Błąd nie wywołuje funkcji. Powinno być: „wywołanie funkcji powoduje błąd” albo podobnie.

Czytałem trochę nt. klasy Invoke, jednakże nie wiem jak ją zaimplementować, i to dla nieokreślonej liczby obiektów.

To nie jest klasa, to jest funkcja, i ją się wywołuje.

Szukam uniwersalnego rozwiązania, które pozwoliło by edytować Form1 z wykorzystaniem osobnego wątku.

Kopiuj
        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i=0; i<10; i++)
            {
                Thread.Sleep(1000);
                Foo(i);
            }
        }

        private void Foo(int i)
        {
            if (InvokeRequired)
                Invoke(new Action<int>(Foo), i);
            else
            {
                label1.Text = i.ToString();
            }
        }

Pamiętaj jednak, że Invoke jest wydajnościowo drogie. Powoduje wstrzymanie bieżącego wątka na czas wykonania w głównym wątku tego co jest pod Invoke.

Ale to samo można uzyskać jednowątkowo, z wykorzystaniem async/await - i być może w twoim przypadku też można się pozbyć osobnego wątka.

Kopiuj
        private async void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                await Task.Delay(1000);
                label1.Text = i.ToString();
            }
        }

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.