Entwickler-Ecke

WinForms - Threadübergreifender Vorgang bei Steuerelement listbox


master147 - Do 31.01.13 17:12
Titel: Threadübergreifender Vorgang bei Steuerelement listbox
Hallo,

ich programmiere zur Zeit eine Server-Client Lösung. Dabei soll der Client in regelmäßigen Abständen dem Server seinen Status geben (Erfolg, Fehler).
Der Server soll den Befehl dann erkennen und in die entsprechende Listbox eintragen. Dabei entsteht bei mir aber ein Vorgang auf das Steuerelement.

Hier ist der Server Quelltext. Beim Thread Feedback kommt der Fehler beim schreiben in die Listbox.


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:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
 private void Form1_Load(object sender, EventArgs e)
        {
           
         
            Thread Thread = new Thread(new ThreadStart(Commands));
            Thread.IsBackground = true;
            Thread.Start();
            Thread Thread1 = new Thread(new ThreadStart(Feedback));
            Thread1.IsBackground = true;
            Thread1.Start();
        }

        public void Commands()
        {
            var Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint EndPoint = new IPEndPoint(IPAddress.Any, 7778);
            Socket.Bind(EndPoint);
            Socket.Listen(10);
            byte[] ByteData = new byte[1025];
            Socket s = Socket.Accept();

            int Length = s.Receive(ByteData);
            string strgData;
            strgData = System.Text.Encoding.ASCII.GetString(ByteData, 0, Length);

            if (strgData.StartsWith("#") && strgData.EndsWith("#"))
            {
                Socket.Close();
                MessageBox.Show("habe " + strgData + "  empfangen");
                strgData = strgData.Remove(01);
                MessageBox.Show("Erste # weg " + strgData);
                strgData = strgData.Replace("#""");
                MessageBox.Show("Zweite # weg " + strgData);

                if (strgData.StartsWith("Windows"))
                {
                    if (strgData == "Windows XP")
                    {

                    }
                    else
                    {

                    }
                }

                if (strgData.StartsWith("Software"))
                {
                    string benutzer;
                    string software;
                    string[] swv = strgData.Split('.');
                    benutzer = swv[2];
                    MessageBox.Show(swv[0]);
                    MessageBox.Show(swv[1]);
                    MessageBox.Show(swv[2]);
                    MessageBox.Show(swv[3]);

                    software = swv[1];

                    //Aufteilung nach verfügbarer Software

                    if (software == "VLC")
                    {

                        Dateiname = "VLC.msi";
                        Dateiname1 = "vlc-1.1.11-win32.exe";
                        string Dateinameneu = @"\soft" + Dateiname;
                        string Dateinameneu1 = @"\soft" + Dateiname1;
                        string Dateinamescript;
                        Dateinamescript = "soft" + Dateiname;

                        //SWV-Benutzerverzeichnis erstellen
                        string Pfad = @"C:\SWV";
                        string Pfadanlegen = System.IO.Path.Combine(Pfad, benutzer);
                        System.IO.Directory.CreateDirectory(Pfadanlegen);
                        MessageBox.Show("Datei erstellt");
                        //Datei in das SWV\Benutzerverzeichnis kopieren

                        Quelle = @"C:\SWV\Programme\VLC\" + Dateiname;
                        Ziel = @"C:\SWV\" + benutzer + Dateinameneu;
                        File.Copy(Quelle, Ziel, true);
                        Quelle = @"C:\SWV\Programme\VLC\" + Dateiname1;
                        Ziel = @"C:\SWV\" + benutzer + Dateinameneu1;
                        File.Copy(Quelle, Ziel, true);
                        MessageBox.Show("Copy Programm erfolgreich");

                        File.WriteAllText(Directory.GetCurrentDirectory() + @"\" + benutzer + ".cmd"@"xcopy \\vmab02\c$\SWV\" + benutzer + @"\* C:\SWV\Programme\" + "\n");
                        File.AppendAllText(Directory.GetCurrentDirectory() + @"\" + benutzer + ".cmd""msiexec /package " + @"C:\SWV\Programme\" + Dateinamescript + " /quiet");

                        Quelle = Directory.GetCurrentDirectory() + @"\" + benutzer + ".cmd";
                        Ziel = @"C:\SWV\" + benutzer + @"\" + "start_SWV.cmd";
                        File.Copy(Quelle, Ziel, true);
                        MessageBox.Show("Copy cmd erfolgreich");
                    }
           

        }

        public void Feedback()
        {
            string benutzer, software;

            var Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint EndPoint = new IPEndPoint(IPAddress.Any, 7779);
            Socket.Bind(EndPoint);
            Socket.Listen(10);
            byte[] ByteData = new byte[1025];
            Socket s = Socket.Accept();

            int Length = s.Receive(ByteData);
            string strgData;
            strgData = System.Text.Encoding.ASCII.GetString(ByteData, 0, Length);

            if (strgData.StartsWith("+") && strgData.EndsWith("+"))
            {
                Socket.Close();
                strgData = strgData.Remove(01);
                MessageBox.Show("Erste+ weg " + strgData);
                strgData = strgData.Replace("+""");
                MessageBox.Show("Zweite + weg " + strgData);
                string[] swv = strgData.Split('.');
                MessageBox.Show("Split" + strgData);
                benutzer = swv[1];
                MessageBox.Show("Benutzer " + benutzer);
                software = swv[2];
                MessageBox.Show("Software " + software);
                

               listbox1.items.Add("Hallo");
               

            }
            
        }


        }

    }


Mich würde es sehr freuen wenn ihr mir helfen würdet den Fehler zu finden.


Ralf Jansen - Do 31.01.13 17:54

Zugriff auf die UI müssen aus dem Thread erfolgen dem auch die UI gehört, das sollte auch in der Exception die du erhälst stehen.
Um den entscheidenden Code im richtigen Thread auszuführen mußt du die Invoke Methode eines Controls aus dem Thread in dem du den Code ausführen willst benutzen und in dessen Context den Zugriff auf die Controls stattfinden lassen. Also ersetze


C#-Quelltext
1:
listbox1.items.Add("Hallo");                    


durch


C#-Quelltext
1:
2:
3:
this.Invoke((MethodInvoker)delegate {
    listbox1.items.Add("Hallo");
});