VB.NET > Thread mit übergabewerten.
Sephiroth
- programmiertechnik
Hi.
Ich hoffe, hier kann mir jemand helfen.
Ich verzweifel gerade daran, wie ich ein Thread starten kann, welcher einen Übergabewert haben möchte:
--VB.NET--------------------------------------------------
Private Sub irgend_eine_Funktion()
MessageBox.Show(irgend_ein_Wert)
End Sub
Private Sub irgend_eine_Funktion_mit_Werten(ByVal irgend_ein_Wert As Object)
MessageBox.Show(irgend_ein_Wert)
End Sub
Private Sub Button1Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles hutton1.Click
Dim th As New System.Threading.Thread(AddressOf irgend_eine_Funktion)
End Sub
----------------------------------------------------
Wie das mit einer Funktion ohne Übergabewerte funktioniert, weiß ich.
Jedoch weiß ich nicht, wie ich einen Übergabewert an diese Funktion sende.
Google macht mich nicht schlau. Und die Gallileo-Handbücher sind genauso verwirrend.
Kann mir einer (wenn möglich) das mal erläutern?
MFG
Sephiroth
Hallo,
Private Sub irgend_eine_Funktion_mit_Werten(ByVal irgend_ein_Wert As Object)
MessageBox.Show(irgend_ein_Wert)
End SubPrivate Sub Button1Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles hutton1.Click
Dim th As New System.Threading.Thread(AddressOf irgend_eine_Funktion)
End Sub
Und die Gallileo-Handbücher sind genauso verwirrend.
fand ich zu diesem Thema nicht.
Ein simples Beispiel, simpler als Deines, das ein eigenes Formular mit dem Namen MessageBox verwendet:
Public Class Form1
' Prozedur, die in einem neuen Thread aufgerufen werden soll
' Wie Du richtig erkannt hast, muss der Parameter als Objekt übergeben
' werden
Private Sub MyProcedure(ByVal obj As Object)
' Wende die toString-Methode an, die *jedes* Objekt in VB.NET hat,
' um den Übergabeparameter in eine Zeichenkette zu wandeln, das was
' eine Messagebox haben will.
MsgBox(obj.toString)
End Sub
Private Sub Button1_Click( _
ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click
' Soweit warst Du ja schon.
Dim myThread As New System.Threading.Thread(AddressOf MyProcedure)
' Du musst nur noch den Thread starten :-)
' Ein typisches "Hallo Welt"-Programm
myThread.Start("Hallo Thread!") ' MsgBox erscheint mit dem Inhalt "Hallo Thread!"
End Sub
End Class
Freundliche Grüße
Vinzenz
Hallo, ergänzend
es gibt zwei Arten von ThreadStart Delegates:
Wenn start einem Delegaten eine Methode mit/ohne Parameter direkt in den new Thread() Konstruktor gegeben wird, wählt .Net selbst den richtigen Delegaten aus.
/* ja, ich weiss, ist C# */
Thread t = new Thread(delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); });
t.Start("Frank");
Allerdings muss man nicht immer einen ganzen kompletten Thread aufmachen, wenn man ihn nicht für die gesamte Lebensdauer braucht.
Für kurze abgeschlossene Aufgaben empfiehlt sich der ThreadPool mit der Methode QueueUserWorkItem:
ThreadPool.QueueUserWorkItem(delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); }, "Frank");
Über das asnychrone Programmiermodell mit BeginInvoke und EndInvoke ist das natürlich auch möglich
delegate void SampleDelgate(object o);
SampleDelgate d = delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); };
d.BeginInvoke("Frank", delegate(IAsyncResult ar)
{
AsyncResult aResult = (AsyncResult)ar;
SampleDelgate temp = (SampleDelgate)aResult.AsyncDelegate;
temp.EndInvoke(ar);
}, null);
Und bitte Threads nicht mit .Abort() abbrechen sondern einfach auslaufen lassen.
Ciao, Frank
Hallo, ergänzend
es gibt zwei Arten von ThreadStart Delegates:
- ThreadStart (ohne Parameter)
- ParameterizedThreadStart (mit object als Parameter)
Wenn start einem Delegaten eine Methode mit/ohne Parameter direkt in den new Thread() Konstruktor gegeben wird, wählt .Net selbst den richtigen Delegaten aus.
/* ja, ich weiss, ist C# */
Thread t = new Thread(delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); });
t.Start("Frank");Allerdings muss man nicht immer einen ganzen kompletten Thread aufmachen, wenn man ihn nicht für die gesamte Lebensdauer braucht.
Für kurze abgeschlossene Aufgaben empfiehlt sich der ThreadPool mit der Methode QueueUserWorkItem:
ThreadPool.QueueUserWorkItem(delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); }, "Frank");
Über das asnychrone Programmiermodell mit BeginInvoke und EndInvoke ist das natürlich auch möglich
delegate void SampleDelgate(object o);
SampleDelgate d = delegate(object o) { Console.WriteLine("Hello {0}!", o.ToString()); };
d.BeginInvoke("Frank", delegate(IAsyncResult ar)
{
AsyncResult aResult = (AsyncResult)ar;
SampleDelgate temp = (SampleDelgate)aResult.AsyncDelegate;
temp.EndInvoke(ar);
}, null);Und bitte Threads nicht mit .Abort() abbrechen sondern einfach auslaufen lassen.
Ciao, Frank
Danke. Das hilft mir schon gewaltig weiter.
Jetzt habe ich aber leider ein weiteres Problem:
(ich poste den code nicht, weil dieser aus dem Gallileo-Computing-Handbuch stammt und minimal abgewandet ist. Mehr infos im weiteren Text)
Dazu muss ich aber erstmal erläutern, was ich vor habe:
Ich möchte ein Multiuser-Chat via Socket erstellen. Will mich da erstmals durchfriemeln. Das Gallileo-computing-handbuch beschreibt aber leider nur ein Singe-User-Chat, welcher nur einen einzigsten Socket parrallel annehmen kann.
Nun versuchte ich logischerweise, das übergebende Socket an einen eigenen Thread weiterzureichen, der das solange handhabt, bis getrennt wird und die hauptfunktion unbeeinflusst weiterläuft.
Jedoch funktioniert das irgendwie nicht. Sowie ich verbinden will, schmeißt er die verbindung sofort raus und das programm schmiert ab.
Quellcode kennt wahrscheinlich jeder aus dem Gallileo-Computing-Handbuch. Dort einfach ab "socket.Accept()" den übergabewert an ein eigenen Thread geschickt und das ganze weiterlaufen lassen. (die server.Listen(1) in einer Do While True-Schleife, die quasi nie endet und nur durchs Try/Catch beendet wird)
Möchte gerne ein möglichst simples beispiel für einen server, wo mehrere clients einfach akzeptiert werden können. (multiuser-chat)
Wäre für Lösungsbeispiele (möglichst in VB.NET) sehr dankbar.
Mit freundlichen Grüßen
Sephiroth
Hi, bitte kein TOFU und kein TUFO :) Es reicht völlig, wenn du die einzelnen Textpassagen zitierst, auf die du antworten willst, alles andere ist nur Ballast für dieses arme Board ... äh ... Forum.
Wieviel Sinn macht ein Single-User-Chat? Für Leute, die gern Selbstgespräche führen vielleicht nicht schlecht aber sonst? Für mich ein Programmierbeispiel abseits der Praxis. ;)
Die suche nach "chat .net socket thread" hätte dich recht schnell zu mehreren Ergebnissen (auch bei CodeProject) gebracht, vielleicht nicht gerade immer in VB.net. Aber C# zu VB.Net zu konvertieren ist doch nicht so schwer, ich muss jeden Tag VB6 zu C# umschreiben ;)
Was soll ein ChatServer machen?
Sowas macht man meisten mit zwei sich synchronisierenden Threads. Also System.Threading.Thread, so wie du schon vorhattest.
Die beiden Threads synchronisieren sich über eine System.Collections.Generic.Queue(Of T). Beide hängen drauf mittels lock oder Monitor.Enter und signalisieren sich mittels Monitor.Pulse(deinQueueObject) und Monitor.Wait() in einer unendlichen[1] Schleife.
[1] die Beendigung der Schleife regelst du über eine statische Variable nach dem Schema
while(true)
{
if(terminateLoop) break;
}
..., welche du vom Hauptthread (dem UI Thread z.b. setzt)
Und bitte nicht mit Exceptions irgendwo rausspringen, Exceptions sind böse, besonders die, die du selbst wirfst. ;)
BTW: Gallileo Literatur ist nicht grad das Gelbe vom Ei. ISBN: 0-7356-1579-9 oder 0-7356-1721-X wären da sicher besser. ;)
Ciao, Frank