Wielowątkowość pierwsze kroki

0

Dalczego moja wielowątkowośc w tym przypadku nie działa?

 Thread thread;


        private void button1_Click(object sender, EventArgs e)
        {
            
        thread = new Thread(car1);
        thread.Start();


        }

        public void car1()
        {
            int x = this.Width;
            int y = this.Height;

            pictureBox1.Width = 50;
            pictureBox1.Height = 25;

            Graphics g = pictureBox1.CreateGraphics();
            Brush b = new SolidBrush(Color.Black);
            g.FillRectangle(b, 0, 0, pictureBox1.Width - 1, pictureBox1.Height - 1);

            pictureBox1.Invoke(new MethodInvoker(delegate ()
            {
                pictureBox1.Top = y / 4 - pictureBox1.Height;

                for (int i = 0; i < x - pictureBox1.Width + 15; i++)
                {
                    pictureBox1.Left = i;
                    for (float j = 0; j < 3000000; j++) ;
                }
                
            }));
            }
0

Co znaczy nie działa?

Lepiej się do tego nada Task

0

A wiesz co robi Invoke?

0

To zadziała, ale nie polecam.
Najlepiej tak jak pisał @ŁF w komentarzu, w Invoke tylko ustawienie właściwości Left, reszta poza.

public async Task car1()
        {
            int x = this.Width;
            int y = this.Height;
 
            pictureBox1.Width = 50;
            pictureBox1.Height = 25;
 
            Graphics g = pictureBox1.CreateGraphics();
            Brush b = new SolidBrush(Color.Black);
            g.FillRectangle(b, 0, 0, pictureBox1.Width - 1, pictureBox1.Height - 1);
 
            pictureBox1.Invoke(new MethodInvoker(async () =>
            {
                pictureBox1.Top = y / 4 - pictureBox1.Height;
 
                for (int i = 0; i < x - pictureBox1.Width + 15; i++)
                {
                    pictureBox1.Left = i;
                    await Task.Delay(100);
                }
 
            }));
            }
 

Ale to tak na szybko, niesprawdzane bo nie mam teraz czasu.
Jak chcesz to tylko przesuwać to nie potrzebujesz Thread/Task. Wystarczy samo uzycie async/await.

0

Prosty przykład z Threads oraz SynchronizationContext. Mało osób wie że w .NET 2.0 został wprowadzon SynchronizationContext. Zapewne jest to o wiele piękniejsze narzędzie do aktualizacji UI niż method-a Invoke kontolki . Choć oczywiście każde rozwiązanie ma swoje plus i minusy.

Tu kilka przykładów z wielowątkowości. Oraz poniższy przykład nieco lepiej zrobiony : https://github.com/mjuskiewicz/Multithreading/tree/master/MultithreadingExamples/WindowsFormUiUpdate

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace _4Programmers
{
    public partial class Form1 : Form
    {
        private PictureBox redPictureBox;
        private PictureBox bluePictureBox;
        private SynchronizationContext uiContext;

        public Form1()
        {
            InitializeComponent();
            
            redPictureBox = new PictureBox() { Width = 100, Height = 100 };
            redPictureBox.BackColor = Color.Red;

            bluePictureBox = new PictureBox() { Width = 100, Height = 100 };
            bluePictureBox.BackColor = Color.Blue;

            var button = new Button();
            button.Dock = DockStyle.Bottom;
            button.Text = "Animacja";

            button.Click += Button_Click;

            Controls.Add(redPictureBox);
            Controls.Add(bluePictureBox);
            Controls.Add(button);

            uiContext = WindowsFormsSynchronizationContext.Current;
        }

        private void Button_Click(object sender, EventArgs e)
        {
            var redThread = new Thread(SimpleInvokeExample);
            redThread.Start();

            var blueThread = new Thread(SynchronizationContextExample);
            blueThread.Start();
        }

        private void SimpleInvokeExample()
        {
            for (int i = 0; i < Width; i += 10)
            {
                this.Invoke(new MethodInvoker(() => 
                {
                    redPictureBox.Left = i;
                })); 

                Thread.Sleep(100);
            }
        }

        private void SynchronizationContextExample()
        {
            for (int i = Width; i >= 0; i -= 10)
            {
                uiContext.Post(new SendOrPostCallback((parameter) =>
                {
                    bluePictureBox.Left = (int) parameter;
                }), i);

                Thread.Sleep(100);
            }
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1