C # -Formularsteuerelemente werden mit Multithreading nicht aktualisiert

Ich habe mit Multithreading herumgespielt und einige der Fragen hier nachgelesen, aber ich habe hier keine Antwort gefunden, die direkt auf meine Bedenken eingeht.

Ich habe eine Anwendung, die auf einem einzelnen Thread ausgeführt wird, mit Ausnahme eines Fortschrittsbalkens in einem separaten Fenster. Basierend auf meinen Recherchen muss ich einen neuen Thread für dieses Formular erstellen, der die Steuerelemente des Formulars neu zeichnet, wenn sich seine Eigenschaften ändern. Ich habe das Problem auf ein einfaches Beispiel unten reduziert:

Hier ist das Hauptprogramm:

class Program
{
    static MyForm form;

    static void Main(string[] args)
    {
        form = new MyForm();
        form.Show();

        doWork();

        form.Close();
    }

    //arbitrary example of processing that takes some period of time
    static void doWork()
    {
        while (form.Value < 100000) 
        {
            form.ChangeVal();
            Thread.Sleep(1);
        }
        return;
    }
}

... Und hier ist das Formular. Ich beziehe die automatisch generierten Inhalte von VS nicht mit ein.

public partial class MyForm : Form
{
    private int val;
    public int Value
    {
        get { return val; }
        set { val = value; }
    }

    public Thread GUIupdater;


    public MyForm()
    {
        InitializeComponent();
        this.Refresh();
    }

    private void MyForm_Load(object sender, EventArgs e)
    {
        GUIupdater = new Thread(new ThreadStart(GUIupdaterThread));
        GUIupdater.Start();

        this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(killThreadOnClose);
    }

    public void ChangeVal()
    {
        val++;
    }

    private void changeLabel(string s)
    {
        label.Text = s;
        label.Refresh();
    }
    private delegate void labelChanger(string s);
    private void GUIupdaterThread()
    {
        while (true)
        {
            Invoke(new labelChanger(changeLabel), new object[]{val.ToString()} );
            Thread.Sleep(100); //100 ms
        }
    }
    private void killThreadOnClose(object sender, FormClosingEventArgs e)
    {
        GUIupdater.Abort();
    }
}

So ist meine Absicht hier, die Berechnungen ständig laufen zu lassen, wobei die Grafiken des Fensters relativ schnell aktualisiert werden. Wenn ich das Programm ausführe, wird die Aufruffunktion jedoch nur einmal aufgerufen und das Label wird nie aktualisiert!

Alle Rückmeldungen sind willkommen. Wenn Sie den Code in einer IDE anzeigen möchten, können Sie mein Projekt von @ herunterladeHie

Edits:

Wenn ich Console.WriteLine-Anweisungen hinzufüge, stellte ich fest, dass die GUIupdaterThread-Schleife (die die GUI aktualisieren soll) in der Invoke-Anweisung immer "bricht" und niemals "Thread.Sleep" erreicht. Ich habe es in 'BeginInvoke' geändert, wodurch die Schleife ordnungsgemäß funktioniert. Dies hat jedoch nichts an der Tatsache geändert, dass die GUI nicht aktualisiert wird.

ERLÄUTERUNGEN:

Über mein 'aktuelles' Projekt:

Der Hauptthread hier in "Programm" simuliert meine Software, ein Plugin, das eine Schnittstelle implementiert. Meine Entscheidung, val / value in diesem Thread zu ändern, nicht in dem vom Fenster erstellten Thread, war absichtlich. Ich bin auf die Verwendung von .NET 4.0 beschränkt. neuere Funktionen können mir nicht helfen

Antworten auf die Frage(8)

Ihre Antwort auf die Frage