Hallo ich wollte mal fragen welche die einfachste lösung ist einen string aus einem Thread wo ich daten vom TCPClient Empfange einlesen kann. gruß Peter
Bitte beschreibe das Problem noch mal neu.
Also ich hab einen Thread. In dem ich dauernd die Receive-Daten des TCP Client empfange. Diese will ich in einer Richtextbox anzeigen lassen und bekomme immer diesen Fehler! "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement rtb_tcp_client_action erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."
Peter schrieb: > "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das > Steuerelement rtb_tcp_client_action erfolgte von einem anderen Thread > als dem Thread, für den es erstellt wurde." http://msdn.microsoft.com/de-de/library/ms171728.aspx
Also in Loadform für ich das hier aus
1 | Thread t1 = new Thread(new ThreadStart(this.tcpClientReceive)); |
2 | t1.Start(); |
Wenn die Verbindung dann steht sollte er mir ja die Daten an den TCP-Client gesendet werden in die Variable "tcpclientreceivedata" schreiben. Diese wird dann in einem Timertick in eine Textbox geschrieben. Da wird aber nie was angezeigt.
1 | private void tcpClientReceive() |
2 | {
|
3 | if (tcpClient.Client != null) |
4 | {
|
5 | if (tcpClient.Client.Connected) |
6 | {
|
7 | try
|
8 | {
|
9 | String responseData = String.Empty; |
10 | tcpClientStream = tcpClient.GetStream(); |
11 | StreamReader clientStreamReader = new StreamReader(tcpClientStream); |
12 | |
13 | Byte[] data = new Byte[4096]; |
14 | Int32 bytes = tcpClientStream.Read(data, 0, data.Length); |
15 | responseData = Encoding.ASCII.GetString(data, 0, bytes); |
16 | this.tcpclientreceivedata = this.tcpclientreceivedata + responseData; |
17 | }
|
18 | catch
|
19 | {
|
20 | ;
|
21 | }
|
22 | }
|
23 | }
|
24 | }
|
Peter schrieb: > Wenn die Verbindung dann steht sollte er mir ja die Daten an den > TCP-Client gesendet werden und wenn sie nicht steht, dann wird dein neuer thread einfach wieder beendet.
Peter schrieb: > Da wird aber nie was angezeigt. da wir nicht den Rest vom code kennen, kann hier auch keiner weiterhelfen. Und wenn du ein catch ohne sinnvolle fehlerbeandlung schreibst, brauchst du dich nicht wundern das man keine fehler findet. Hast du dir den Link von MS durchgelesen dort steht alles drin was man beachten muss wenn man von einem Thread auf die gui zugreifen will.
Peter II redet viel, stellt sich aber absichtlich doof. Ggf. ist er es auch wirklich. Er versteckt seine mangelnde Ahnung, indem er Formfehler bemängelt. Trotzdem existiert ein großes Verlangen nach Profilierung. Themenwechsel: Offensichtlich möchtest Du Daten an ein Control übergeben. Die Eigenschaften diese Controls dürfen ggf. nur aus dem Vordergrundprozess heraus geändert werden. Ob dies erforderlich ist, kannst Du mit der Methode InvokeRequired des betreffenden Controls herausfinden. In Deinem Fall müssen offensichtlich die Daten aus dem Receive-Thread einsynchronisiert werden. Beispiel:
1 | void Write(string Text) |
2 | {
|
3 | if (MyControl.InvokeRequired) |
4 | MyControl.Invoke(new Action<string>(Write), (Text)); |
5 | else
|
6 | MyControl.Text = Text; |
7 | }
|
Möglicherweise gibt es noch weitere Probleme, aber mit dem Code da oben erreichst Du zumindest schon einmal Test- und Debugausgaben.
Wenn es genau das Problem ist, von dem Peter III schreibt, kannst du auch das MVVM-Pattern nehmen - ist eleganter aber nicht ganz einfach selbst anzueignen.
Peter schrieb: > Hallo > > ich wollte mal fragen welche die einfachste lösung ist einen string aus > einem Thread wo ich daten vom TCPClient Empfange einlesen kann. > > gruß Peter Peter III schrieb: > In Deinem Fall müssen offensichtlich die Daten aus dem Receive-Thread > einsynchronisiert werden. Hallo Peter, der Perter III hat Recht, so etwas kann man elegant über "Invoke" und co. machen. ^^Die einfachste Lösung ist meiner Meinung nach aber, die empfangenen Daten in einen String abzulegen und mit einem Timer in dem anderen Thread den String in die RichTextBox zu schreiben. Also in deiner Form z.B.: class Form1 .... Timer t; string textReceived = ""; // evtl public static string (wenn andere Form) public Form1() { ... t = new Timer(); t.Intervall = 100; ... } public Form1_Load(..) { t.Start(); } ... Form1_Closing(..) { t.Stop(); } // Thread, welcher die TCP-Daten empfängt ... textReceived += .... ... // wieder in der 1. Form Timer_tick(..) { richTextBox1.Text = textReceived; } //^^ Der Syntax ist evtl. fehlerhaft. Aber ich denke du weißt, wie ich das meine..
Peter III schrieb: > Peter II redet viel, stellt sich aber absichtlich doof. Ggf. ist er es > auch wirklich. Er versteckt seine mangelnde Ahnung, indem er Formfehler > bemängelt. Trotzdem existiert ein großes Verlangen nach Profilierung. was hast du für ein Problem mit meinen Antworten. Nach dem Peter uns eine Fehlermeldung geschickt hat, habe ich ihn die link geschickt wo drin steht was er zu machen hat? Hätte ich ihm gleich die Lösung gezeigt, hätte er daraus nichts gelernt. Und ja ich kann mit C# umgehen und sehe eine Leere Fehlerbehandlung nicht als Formfehler. Weil man bei einem Problem so nie zu einer Lösung kommt.
A. V. schrieb: > Die einfachste Lösung ist meiner Meinung nach aber, die empfangenen > Daten in einen String abzulegen und mit einem Timer in dem anderen > Thread den String in die RichTextBox zu schreiben. nein das ist der größte Unsinn. Dann man darf nicht aus 2 Threads auf die gleiche Variabel ohne Synchronisation zugreifen. Was passiert wohl wenn gleichzeitig der Timer ausgelöst wird und neue Daten eingeben?
Peter II schrieb: > A. V. schrieb: >> Die einfachste Lösung ist meiner Meinung nach aber, die empfangenen >> Daten in einen String abzulegen und mit einem Timer in dem anderen >> Thread den String in die RichTextBox zu schreiben. > > nein das ist der größte Unsinn. Dann man darf nicht aus 2 Threads auf > die gleiche Variabel ohne Synchronisation zugreifen. Was passiert wohl > wenn gleichzeitig der Timer ausgelöst wird und neue Daten eingeben? Klar geht das. Und wenn "gleichzeitig der Timer ausgelöst wird und neue Daten eingeben" <- werden, dann steht da in der RichTextBox für 100 ms ein alter Wert... uh.. :D
A. V. schrieb: > Klar geht das. Und wenn "gleichzeitig der Timer ausgelöst wird und neue > Daten eingeben" <- werden, dann steht da in der RichTextBox für 100 ms > ein alter Wert... uh.. :D nein dein Programm stützt in einigen Fällen ab. Bei Threadprogrammierung muss man einiges beachten, und das gehört dazu. Man greift nicht aus 2 Threads auf die gleiche Variabel zu. http://msdn.microsoft.com/de-de/library/vstudio/ms173179.aspx Klar geht es zu 99% in diesem Fall gut. aber nicht immer.
Peter II schrieb: > Klar geht es zu 99% in diesem Fall gut. aber nicht immer. Ich gebe Peter III Recht.. Peter III schrieb: > Peter II redet viel, stellt sich aber absichtlich doof. Ggf. ist er es > auch wirklich. Er versteckt seine mangelnde Ahnung, indem er Formfehler > bemängelt. Trotzdem existiert ein großes Verlangen nach Profilierung. Wenn ich mit dem einen Thread NUR schreibe (TCP_Received) und mit dem Anderen (Timer_Tick) NUR lese, dann ist das die einfachste Lösung zum gegebenen Problem.
Peter II schrieb: > nein dein Programm stützt in einigen Fällen ab. dafür gibt es Try catch und schon habe ich statt einem Absturz, mal 100 ms keine neuen Werte.. auch vertretbar.. ;)
A. V. schrieb: > Wenn ich mit dem einen Thread NUR schreibe (TCP_Received) und mit dem > Anderen (Timer_Tick) NUR lese, dann ist das die einfachste Lösung zum > gegebenen Problem. nein ist es nicht. Die Lösung für diese Problem ist http://msdn.microsoft.com/de-de/library/ms171728.aspx und da steht nichts von Timern. > > nein dein Programm stützt in einigen Fällen ab. > dafür gibt es Try catch und schon habe ich statt einem Absturz, mal 100 > ms keine neuen Werte.. auch vertretbar.. ;) scheinbar hast du keine Erfahrung was alles passieren kann. ein Try Catch hilft bei einem Multithreadproblem überhaupt nicht.
Ok Peter II, wann funktioniert meine Lösung, mit dem Timer, zum Problem von Peter nicht?
A. V. schrieb: > wann funktioniert meine Lösung, mit dem Timer, zum Problem von Peter > nicht? wenn gleichzeitig Daten per TCP ankommen und der Timer die GUI aktualisieren will. Timer liest textReceived und Thread schreibt textReceived diese Verhalten ist einfach nicht zulässig, es kann alles möglich passieren. Das ganze wirst du aber nicht Simulieren können. Es wird nur sehr selten schief gehen. Aber es ist ein Problem was man einfach vermeiden könnte.
Peter II schrieb: > wenn gleichzeitig Daten per TCP ankommen und der Timer die GUI > aktualisieren will. dann ist der string, wie du ja sicher weist, immer noch ein "reference type" und die GUI arbeitet dann mit dem evtl. nicht kompletten Inhalt, auf den der pointer zeigt.. und 100 ms später ist wieder alles schick... Was kümmert es den schreibenden Thread, wer gerade auch diese Addresse liest? Da vor Allem eh nichts wirklich parallel passiert.. und es noch einen incomming buffer für TCP/Serial/usw. - Daten gibt...
A. V. schrieb: > Was kümmert es den schreibenden Thread, wer gerade auch diese Addresse > liest? mit welchen wissen stellst du sicher das alle bytes der Adresse auch gleichzeitig aktualisiert werden? Nicht das zwischenzeitlich ein ungültiger werde vorhanden ist. Auch auf das Reference Counting würde ich mich an diese Stelle nicht verlassen. Kann mir durchaus vorstellen das man es auch damit aus dem Tritt bekomme. Es ist einfach nicht zulässig. Oder kannst du mir aus der MSDN einen Artikel zeigen wo es beschrieben ist, das man es machen darf? > Da vor Allem eh nichts wirklich parallel passiert.. und es noch > einen incomming buffer für TCP/Serial/usw. - Daten gibt... das ich nicht lache. Warum gibt es wohl multicore CPUs wenn nichts gleichzeitig passiert. Programmiere doch wie du willst, aber zeige diesen Unsinn nicht anderen Leuten, wenn es eine bessere Lösung dafür gibt. Außerdem ist es sinnlos die GUI alles 100ms mit den gleichen Daten zu aktualisieren. Dafür steigt, wenn auch unwesentlich, nur der Stromverbrauch weil die CPU ständig geweckt wird.
Oh man, der Peter möchte empfangene TCP-Zeichen als String in einer RTB dargestellt haben. Peter schrieb: > ich wollte mal fragen welche die einfachste lösung ist einen string aus > einem Thread wo ich daten vom TCPClient Empfange einlesen kann. Was sind denn das für Antworten von dir zu dem gegebenen Problem? Peter II schrieb: > Dafür steigt, wenn auch unwesentlich, nur der > Stromverbrauch weil die CPU ständig geweckt wird Der schreibt kein High-End-Tool, dass die Wärmeentwicklung der CPU optimiert. Peter II schrieb: > Klar geht es zu 99% in diesem Fall gut. aber nicht immer. Und kann sicher damit leben, dass es theoretisch (nach deiner Meinung) in einem von 100 Fällen nicht funzt. Wobei ich auch nicht an das 1% glaube, indem das Ganze schief gehen soll. Peter II schrieb: > Warum gibt es wohl multicore CPUs wenn nichts > gleichzeitig passiert. -> Welches OS teilt ein so kleines Tool auf mehrere Kerne auf? Mach dich nicht lächerlich. MSDN ist irgendwie immer deine Lösung. Hast du schonmal selbst ein Programm geschrieben, oder zitierst du nur aus den Bedienungsanleitungen?
A. V. schrieb: >> Warum gibt es wohl multicore CPUs wenn nichts >> gleichzeitig passiert. > -> Welches OS teilt ein so kleines Tool auf mehrere Kerne auf? Mach dich > nicht lächerlich. jedes OS teilt mehrere Thread auf mehre mehrere Kerne auf. Dem OS ist die Größe der Anwendung egal. > Oh man, der Peter möchte empfangene TCP-Zeichen als String in einer RTB > dargestellt haben. genau und dafür gibt es eine einfach Lösung, diese Funktioniert zu 100% hat keine Nebenwirkungen, braucht weniger Ressourcen. Und ist nicht schwere umzusetzen als die fehlerhafte Timer-Lösung Warum als mit dem gleichen Aufwand nicht richtig machen? > MSDN ist irgendwie immer deine Lösung. Hast du schonmal selbst ein > Programm geschrieben, oder zitierst du nur aus den > Bedienungsanleitungen? du wirst es nicht glauben, ich mache das beruflich. Und ja die MSDN nutzt ich als Referenz wenn es im C# geht und nicht irgendwelche Foren wo den Leuten falsche Wege gezeigt werden. Und ich verlasse mich nicht auf dinge die scheinbar funktionieren wenn es nicht beschrieben ist das man es so machen darf.
Ich wollte hier jetzt nur eine einfache Lösung zum Problem aufzeigen und mich eigentlich nicht mit jemanden streiten. Ich würde das mit dem Timer machen, wenn ich nur fix die Tcp-Daten dargestellt bekommen haben will. ^^Ich glaube auch nicht, dass das OS dieses Tool auf mehrere Kerne aufteilt (außer evtl. bei i5, i7, und co.) und selbst wenn, glaube ich nicht, dass dann die timer-Lösung Probleme macht. Aus eigener Erfahrung kann ich sagen, dass diese Lösung funzt (bei TCP/Serial/ und was auch immer). Peter II schrieb: > du wirst es nicht glauben, ich mache das beruflich. Klugscheißen und Links von anderen posten, ohne selbst Lösungen zu präsentieren? Deinen Job möchte ich haben.
A. V. schrieb: > Ich würde das mit dem Timer machen, wenn ich nur fix die Tcp-Daten > dargestellt bekommen haben will. kann ja jeder machen wie er will. Ich würde es halt anders machen (und kann auch Gründe dafür liefern). Sag doch mal warum du es nicht mit dem Invoke machen würdest? > Ich glaube auch nicht, dass das OS dieses Tool auf mehrere Kerne > aufteilt (außer evtl. bei i5, i7, und co.) und selbst wenn, glaube ich > nicht, dass dann die timer-Lösung Probleme macht. Ich sitze vor einen I7 und dort wird es aufgeteilt. > Aus eigener Erfahrung > kann ich sagen, dass diese Lösung funzt (bei > TCP/Serial/ und was auch > immer). das haben leider schon viele Leute so gemacht. Und sich dann gewundert das es auf einen I7 irgendwie instabil läuft. Aber in diesem Fall hast du sogar recht. Es würde stabil laufen. C# stellt bei reference types den Zugriff Atomar sicher. http://msdn.microsoft.com/en-us/library/aa691278(v=vs.71).aspx aber die Nachteile mit dem ständigen Refresh bleiben bestehen. > du wirst es nicht glauben, ich mache das beruflich. > Klugscheißen und Links von anderen posten, ohne selbst Lösungen zu > präsentieren? Deinen Job möchte ich haben. das ist ja der Trick daran, ich muss es nicht selber schreiben. Wenn sie MS schon die Arbeit gemacht hat einen verständlichen Artikel incl. Beispiel zu veröffentlichen. Ich habe dafür keine eigene Lösung, ich nehme die "offizielle" und erfinde das Rad nicht neu.
Peter II schrieb: > Sag doch mal warum du es nicht mit dem > Invoke machen würdest? Weil er nach der einfachsten Lösung gefragt hat und man, wenn man es falsch macht (weil man evtl. keine Ahnung hat, von dem was man tut) mit dem Invoke auf eingefrohrene Fenster sieht. Peter II schrieb: > Ich sitze vor einen I7 und dort wird es aufgeteilt. Auf meiner Arbeit haben wir auch i7-Prozis und meine Tools laufen dennoch ohne Thread-Übergreifende-Ex. Peter II schrieb: > Aber in diesem Fall hast du sogar recht. Es würde stabil laufen. C# > stellt bei reference types den Zugriff Atomar sicher. > http://msdn.microsoft.com/en-us/library/aa691278(v... ...blabla... Link auf MSDN... und nach vielen Hin und Her sind wir uns einig, dass meine Lösung funzt...^^Wenn du so viel Zeit auf MSDN verbringst, dann lies doch bitte vorher und meckere dann erst dazwischen.
A. V. schrieb: > Weil er nach der einfachsten Lösung gefragt hat und man, wenn man es > falsch macht (weil man evtl. keine Ahnung hat, von dem was man tut) mit > dem Invoke auf eingefrohrene Fenster sieht. er wollte ein Lösung, nicht die einfachste. Und eingefrohrene habe ich mit Invoke noch nicht geschafft. Scheinbar weis ich also was ich mache. > Auf meiner Arbeit haben wir auch i7-Prozis und meine Tools laufen > dennoch ohne Thread-Übergreifende-Ex. dann fährst du bestimmt auch ohne Gurt Auto, dann es fährt ja auch so. > > Aber in diesem Fall hast du sogar recht. Es würde stabil laufen. C# > > stellt bei reference types den Zugriff Atomar sicher. > > http://msdn.microsoft.com/en-us/library/aa691278(v...> >...blabla... Link auf MSDN... und nach vielen Hin und Her sind wir uns > einig, dass meine Lösung funzt...^^Wenn du so viel Zeit auf MSDN > verbringst, dann lies doch bitte vorher und meckere dann erst > dazwischen. Ich habe immerhin etwas dazugelernt. Ich musste es bis jetzt noch nie machen weil das Problem bei Invoke gar nicht auftritt.
Peter II schrieb: > er wollte ein Lösung, nicht die einfachste. doch guck: Peter schrieb: > ich wollte mal fragen welche die einfachste lösung ist einen string aus > einem Thread wo ich daten vom TCPClient Empfange einlesen kann. Peter II schrieb: > Und eingefrohrene habe ich > mit Invoke noch nicht geschafft. Doch, kann passieren, wenn man keine ahnung hat. denk mal darüber nach, dann kommst du auch darauf. Peter II schrieb: > dann fährst du bestimmt auch ohne Gurt Auto, dann es fährt ja auch so. Wieso? Du hast doch gerade selbst zugegeben, dass es stabil läuft. Ich habe es getestet und es hat gefunzt. Und wenn es doch mal auf Fehler läuft muss ich halt nen Patch basteln. Das macht MS doch genau so. :D
A. V. schrieb: > Wieso? Du hast doch gerade selbst zugegeben, dass es stabil läuft. ja aber ich weiß warum es geht, könntest du es begründen? (Ich habe es getestet zählt nicht, weil man Gleichzeitigkeit nicht Provozieren kann) > Ich habe es getestet und es hat gefunzt. wer denkt multithreaded Probleme ohne Wissen mit Testen zu lösen hat schon verloren. Ich hoffe die schreibst keine Sicherheitsrelevante Programme. Spätesten wenn du das ganze mit einer int64 Variable und keine String machen willst geht es schon nicht mehr.
Peter II schrieb: > Spätesten wenn du das ganze mit einer int64 Variable und keine String > machen willst geht es schon nicht mehr. Das war ja aber auch nicht gefragt. Peter II schrieb: > ja aber ich weiß warum es geht, könntest du es begründen? (Ich habe es > getestet zählt nicht, weil man Gleichzeitigkeit nicht Provozieren kann) Das Tool läuft schon mehrere Monate. Ich habe es nicht nur 2 3 mal probiert. Wie jetzt? Zuerst schreibst du, dass du weißt, dass meine Lösung (laut MSDN) falsch ist. Und jetzt schreibst du, dass sie doch richtig ist, provozierst mich aber, indem du schreibst, dass nur du laut MSDN-Infos weißt warum.. Freak, eh.. dann ließ noch einmal das da, was ich dir vor vielen Posts geschrieben habe: A. V. schrieb: > dann ist der string, wie du ja sicher weist, immer noch ein "reference > type" und schon fällt dir auf, dass ich schon den Unterschied zwischen value und reference type kenne..Vogel!
A. V. schrieb: > Wie jetzt? Zuerst schreibst du, dass du weißt, dass meine Lösung (laut > MSDN) falsch ist. > Und jetzt schreibst du, dass sie doch richtig ist, > provozierst mich aber, indem du schreibst, dass nur du laut MSDN-Infos > weißt warum.. Freak, eh.. dann ließ noch einmal das da, was ich dir vor > vielen Posts geschrieben habe: und was habe ich geschrieben? > mit welchen wissen stellst du sicher das alle bytes der Adresse auch > gleichzeitig aktualisiert werden? Nicht das zwischenzeitlich ein > ungültiger werde vorhanden ist. damit habe ich doch wohl geschrieben, das ich nicht weiß wie es sich verhält. Du weißt es ja scheinbar auch nicht, sondern testest einfach. Ich habe mir die mühe gemacht es rauszufinden, ob es zulässig ist so zu arbeiten und dann die Erklärung gepostet. Leider schreibt niemand anders hier mit, damit werden wir nie rausbekommen was nun die "saubereste" Lösung ist. Egal was wir hier noch schreiben.
^^Die saubere Lösung ist definitiv die mit dem Invoke, aber die mit dem Timer funzt für diesen Zweck halt auch. Peter II schrieb: >> mit welchen wissen stellst du sicher das alle bytes der Adresse auch >> gleichzeitig aktualisiert werden? Nicht das zwischenzeitlich ein >> ungültiger werde vorhanden ist. Wie gesagt, dann zeigt die gui (bzw. die RTB) 100 ms lang einen falschen / nicht kompletten Wert an... uh..
Ein Lock um den Zugriff auf den gemeinsamen String und die Sache wäre vom Tisch. So taugt die Methode bestenfalls für Debugausgaben. Das Statement in MSDN: Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. ist sicherlich so zu verstehen, dass das Kopieren der Referenz atomar ist, nicht aber der Aufruf von Methoden oder überladenen Operatoren der referenzierten Objekte.
Peter III schrieb: > Ein Lock um den Zugriff auf den gemeinsamen String und die Sache wäre > vom Tisch. So taugt die Methode bestenfalls für Debugausgaben. sag ich ja, schön ist es nicht. > ist sicherlich so zu verstehen, dass das Kopieren der Referenz atomar > ist, nicht aber der Aufruf von Methoden oder überladenen Operatoren der > referenzierten Objekte. das macht er aber auch nicht. Es wird jedes mal ein neues Stringobjekt angelegt und der Variabel zugewiesen.
Wenn die Stelle hier:
1 | // Thread, welcher die TCP-Daten empfängt
|
2 | ...
|
3 | textReceived += .... |
4 | ...
|
so aufgelöst wird, dass daraus
1 | textReceived = textReceived + .... |
wird, magst Du recht haben. Damit entginge .NET aber eine schöne Möglichkeit der Optimierung: Wenn der String als Array implementiert ist, welches noch eine verbleibende Speicherkapazität hat, muss der String nicht jedes Mal, wenn Zeichen angehängt werden, umkopiert werden. Dies stellt eine dramatische Performanceverbesserung dar.
Peter III schrieb: > wird, magst Du recht haben. > Damit entginge .NET aber eine schöne Möglichkeit der Optimierung: > Wenn der String als Array implementiert ist, welches noch eine > verbleibende Speicherkapazität hat, muss der String nicht jedes Mal, > wenn Zeichen angehängt werden, umkopiert werden. Dies stellt eine > dramatische Performanceverbesserung dar. wenn man sich String mal genauer anschaut, dann wirst du merken das es keine Möglichkeit gibt einen String wirklich zu ändern. Es wird immer ein neues Objekt erzeugt. http://msdn.microsoft.com/de-de/library/vstudio/362314fe.aspx [...] Zeichenfolgen sind unveränderlich, d. h. der Inhalt eines Zeichenfolgenobjekts kann nicht mehr geändert werden, nachdem das Objekt erstellt wurde, auch wenn die Syntax etwas anderes vermuten lässt. [...]
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.