• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Praca z Task'ami w aplikacji c#

Object Storage Arubacloud
0 głosów
91 wizyt
pytanie zadane 25 sierpnia 2019 w C# przez Fikter Początkujący (280 p.)

Witam,

ostatnio zacząłem się bawić z wielowątkowością, jednak natrafiłem na problem w momencie, gdy próbuję coś zrobić z obiektem głównego wątku (richtextbox) w innym wątku lub Task'u. W dodanym fragmencie, jest tworzona lista Task'ów, w których dodaję delegat na metodę, która ma za zadanie ustawienia właściwość TEXT na wygenerowany tekst o wielkości 10MB. Task'i z tego co zaobserwowałem działają prawidłowo, ponieważ richtextbox jest uzupełniany o tekst w losowej kolejność, a z tego co wiem, nad kolejnością task'ów nie można zapanować i są wykonywane losowo. Problem pojawia się w momencie, gdy klikam na button, wtedy aplikacja zamarza, na chwile, aż do momentu wygenerowania teksu. Liczyłbym na wyjaśnienie co robię źle, lub na potencjalne rozwiązanie tego problemu.

private void Generator_Click(object sender, EventArgs e)
        {
            List<Task> tasks = new List<Task>()
            {
                new Task(delegate
                {
                    set(richTextBox1);
                }),
                new Task(delegate
                {
                    set(richTextBox2);
                }),
                new Task(delegate
                {
                    set(richTextBox3);
                }),
                new Task(delegate
                {
                    set(richTextBox4);
                }),
                new Task(delegate
                {
                    set(richTextBox5);
                })
            };
            tasks.ForEach(x => x.Start());
        }

        private void set(RichTextBox richTextBox)
        {
            if (richTextBox.InvokeRequired)
                richTextBox.Invoke(new Action(() => richTextBox.Text = GenerateText(10485760)));
            else
                richTextBox.Text = GenerateText(10485760);
        }

        private string GenerateText(int size)
        {
            var charSet = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
            var chars = charSet.ToCharArray();
            var data = new byte[1];
            var crypto = new RNGCryptoServiceProvider();
            crypto.GetNonZeroBytes(data);
            data = new byte[size];
            crypto.GetNonZeroBytes(data);
            var result = new StringBuilder(size);
            foreach (var b in data)
            {
                result.Append(chars[b % (chars.Length)]);
            }
            return result.ToString();
        }

 

1 odpowiedź

+1 głos
odpowiedź 25 sierpnia 2019 przez adrian17 Ekspert (344,860 p.)

wtedy aplikacja zamarza, na chwile, aż do momentu wygenerowania teksu

Tak na oko (nie jestem jakoś mocno doświadczony w .NET):

        private void set(RichTextBox richTextBox)
        {
            if (richTextBox.InvokeRequired)
                richTextBox.Invoke(new Action(() => richTextBox.Text = GenerateText(10485760)));
            else
                richTextBox.Text = GenerateText(10485760);
        }

Tutaj w każdym przypadku wywołujesz GenerateText na wątku UI, co oczywiście blokuje UI. Musisz policzyć wartość na swoim wątku, a tylko samo ustawienie .Text zrobić na wątku UI.

Boczne uwagi:

zamiast delegate, nie da się zrobić tak?

new Task(() => set()),

No i nazwa "set" jest dość niefajna (nie zaczyna się wielką literą, jest taka sama jak słowo kluczowe "set").

Podobne pytania

+1 głos
3 odpowiedzi 564 wizyt
pytanie zadane 11 kwietnia 2021 w C# przez tomasz12345 Użytkownik (750 p.)
0 głosów
0 odpowiedzi 96 wizyt
pytanie zadane 21 sierpnia 2019 w C# przez Rafał Ciołek Nowicjusz (180 p.)
0 głosów
1 odpowiedź 216 wizyt

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...