Entwickler-Ecke

WinForms - Thread-Sicher


DareDevil - Di 16.01.07 20:35
Titel: Thread-Sicher
Da ich auf die Visible-Eigenschaft aus einem Thread zugreifen muss ist nun die Frage wie bekomme ich die Visible-Eigenschaft eines Buttons Thread-Sicher.

Ich sag dann schon mal danke da mir bis jetzt immer gut geholfen wurde.

Greez

Pascal


Christian S. - Di 16.01.07 20:54

Hallo!

Das machst Du am Besten mittels der Invoke-Methode der Form. Die Dokumentation enthält da auch Beispiele zu :-)

Grüße
Christian


DareDevil - Di 16.01.07 21:06

Ich glaube irgendwie bin ich zu doof für Delegates.

Oder habe ich mir ein falsches Beispiel angesehen.


Christian S. - Di 16.01.07 21:11

Hm, da musst Du jetzt schon genauer werden. Was verstehst Du denn nicht?


DareDevil - Di 16.01.07 21:16

Einmal was das Delegate überhaupt bewirkt und funktioniert.
Mit Delegates habe ich schon öfters mal versucht mich auseinander zusetzen aber hat nie so wirklich funktioniert.


Christian S. - Di 16.01.07 21:46

Also, mit einem Delegate legst Du die Signatur einer Methode fest, definierst im Prinzip einen Methoden-Typen.

C#-Quelltext
1:
public delegate void aDelegate(String foo);                    

Damit sagst Du, dass Methoden, welche nichts (void) zurückgeben und einen String "foo" als Parameter erhalten vom Typ "aDelegate" sind.

Wozu braucht man das jetzt? Wenn Du einen Delegate hast, kannst Du auch Variablen anlegen, die von diesem Typ sind:

C#-Quelltext
1:
public aDelegate aMethod;                    


Diese kannst Du dann aufrufen:

C#-Quelltext
1:
2:
if (aMethod != null//wenn der Variable ein Wert zu gewiesen wurde
    aMethod("bar");


Du rufst also über den Variablennamen auf, welche Methode man dieser Variable auch immer vorher zugewiesen hat.

Ich habe mal eine kleine Konsolenanwendung als Verdeutlichung geschrieben:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass aTestClass = new TestClass();

            aTestClass.DoTest();
            Console.ReadLine();
        }
    }

    public class TestClass
    {
        public delegate void aDelegate(String Foo); //Der Delegate / "Funktionentyp"

        public aDelegate aMethod; //Die Variable

        public void OneMethod(String Foo) //Eine Methode, welche dem Delegate entspricht
        {
            Console.WriteLine("Method 1: " + Foo);
        }

        public void AnotherMethod(String Foo) //Noch eine Methode, welche dem Delegate entspricht
        {
            Console.WriteLine("Method 2: " + Foo);
        }

        public void DoMethod() //Ruft die Methode auf, welche in der Variable "aMethod" drin steckt
        {
            if (aMethod != null//wenn der Variable ein Wert zu gewiesen wurde
                aMethod("bar"); //führe die Methode aus
        }

        public void DoTest()
        {
            aMethod = OneMethod; //Der Variable die erste Methode zuweisen
            DoMethod(); //Ausführen

            aMethod = AnotherMethod; //Der Variable die zweite Methode zuweisen
            DoMethod();  //Ausführen
        }
    }
}


Hoffe, damit wird das etwas klarer.


DareDevil - Di 16.01.07 22:16

So ist das auch verständlich.

Muss man dafür extra einen Delegate anlegen oder geht das auch ohne?

Und nochmal danke für die Hilfe.


Christian S. - Di 16.01.07 22:21

Ja, meines Wissens musst Du einen Delegate dafür anlegen.

Ach ja, was mir gerade auffällt: die Doku für Invoke (Delegate, Object[]) ist deutlich aufschlussreicher als für Invoke(Delegate)


Robert_G - Mi 17.01.07 00:49

user profile iconChristian S. hat folgendes geschrieben:
Ja, meines Wissens musst Du einen Delegate dafür anlegen.

Ach ja, was mir gerade auffällt: die Doku für Invoke (Delegate, Object[]) ist deutlich aufschlussreicher als für Invoke(Delegate)
Man sollte aber beachten, dass man am besten eine Variable vom Typ MethodInvoker übergibt. Dieser overload von Invoke ist schneller als der andere.
Um Parameter zu übergeben kann man auch schön anonyme Methoden nehmen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
string mööp = "hallo";
MethodInvoker method = delegate
{
  someControl.Text = mööp;
};

someControl.Invoke(method);


DareDevil - Mi 17.01.07 13:12

Was sind den nun anonyme Methoden


Kha - Mi 17.01.07 16:08

Das ist nun wirklich ausführlich im SDK beschrieben - sofern man Delegates verstanden hat.