vb 2010 form aus einem Thread öffnen

cookyman

Grünschnabel
Hallo Community,

ich bin langsam am verzweifeln.

Ich habe in einem Modul ein Thread am laufen,
weil ich von jeder Form auf diesen Thread zugreifen möchte,
weil mir dort Mein Server auch mal Nachrichten schickt,
die dann beim Client auch angezeigt werden soll.

Hier erstmals mein Code:

Code:
Imports System.Net.Sockets
Imports System.IO
Module verbindung_herstellen
	Private stream As NetworkStream
	Private streamw As StreamWriter
	Private streamr As StreamReader
	Private client As New TcpClient
	Private server_mail As New Threading.Thread(AddressOf server_listen)

	Dim IP As String = "**************"
	Dim Port As Integer = ************

	Public Function verbinden()
    	Try
        	client.Connect(IP, Port)
        	If client.Connected Then
            	stream = client.GetStream
            	streamw = New StreamWriter(stream)
            	streamr = New StreamReader(stream)
            	client_send(HDWID)
            	Register = streamr.ReadLine()
            	server_mail.Start()
            	Return ("yes")
        	Else
            	Return ("no")
        	End If
    	Catch
        	Return ("no")
        	client.Close()
    	End Try
	End Function

	Sub client_send(ByVal text As String)
    	streamw.WriteLine(text)
    	streamw.Flush()
	End Sub
	Private Sub server_listen()
    	While client.Connected
        	Dim auswährten() As String = Split(streamr.ReadLine(), ";")
        	If auswährten(0) = "server_send" Then
            	MsgBox(auswährten(1))
        	ElseIf auswährten(0) = "register_ok" Then
            	MsgBox(auswährten(1))
                



                ' hier möchte ich, das er mir meine Login Form öffnet
                  und die Register Form schließt.




        	ElseIf auswährten(0) = "userabfrage" Then
            	MsgBox(auswährten(1))
        	ElseIf auswährten(0) = "regabfrage2" Then
            	MsgBox(auswährten(1))
        	ElseIf auswährten(0) = "Registrier Fehler" Then
            	MsgBox(auswährten(1))
            	client_send("logout")
        	ElseIf auswährten(0) = "logout_ok" Then
            	client.Close()
            	stream.Close()
            	streamw.Close()
            	streamr.Close()
            	server_mail.Abort()
            	server_mail.DisableComObjectEagerCleanup()
            	Application.Exit()
        	End If
    	End While
	End Sub
End Module


Meine versuche mit login.show() waren leider Ergebnis los,
da sich dann die Form aufhängt.

Ich habe auch schon Google bemüht,
und raus gefunden das es dafür Delegaten gibt,
ich habe es damit auch versucht,
nur leider komme ich mit denn delegaten noch nicht zurecht.

Ich sitze jetzt seit Sonntag an diesem Problem und komme auf keine Lösung,
ich hoffe ihr könnt mir helfen,
da ich sonst mein Projekt nicht weiter machen kann.

Bitte helft mir dabei.
 
Hi

Du musst wieder zurück in den UI-Thread, dies ist mit Delegates zu bewerkstelligen. Da warst du also auf der richtigen Spur :)
Wo hast du denn damit Probleme?
Würde dir dafür empfehlen, wenn du damit keine Erfahrungen hast, erstmal eine kleine TestApp zu erstellen, mit der du rumprobieren kannst, wie Cross-Thread-Kommunikation aufzubauen ist.
 
Hallo,

ich habe mir im Internet bereits darüber schon einiges angeschaut und habe mir dann folgendes zusammen geschustert Test weiße.

Code:
Private Delegate Sub d_showSomeFrm()


Das habe ich im gleichen modul gepackt gehabt am ende:
Code:
Private Sub Test()
login.Show()
reg.Close()
End Sub

Und damit wollte ich das aufrufen:
Code:
Me.Invoke(New d_showSomeFrm(AddressOf Test))

Und da habe ich dann das Problem,
das er im Modul beim Aufruf Me. leider nicht erlaubt.

Darauf hin habe ich dann das Private Sub in die register Form gepackt und wollte sie dann damit aufrufen :

Code:
reg.Invoke(New d_showSomeFrm(AddressOf reg.Test))

Da Kamm dann aber auch wieder ein Fehler,
genauen Fehler kann ich jetzt gerade nicht sagen,
da ich los zur Arbeit muss.

Ich sitze jetzt seit Sonntag an diesem Problem,
und ohne das ich das behebe kann ich mein Programm leider nicht weiter machen.

Ich möchte mich schon mal im voraus bedanken bei euch.

Ich hoffe ihr könnt mir helfen,
bin echt am verzweifeln damit. :(
 
Hallo,

ich habe nun folgendes nochmals versucht:

im Modul habe ich erstmals das delegate deklariert:

Code:
Public Delegate Sub mydel()

dann habe ich im Thread wo ich die Form aufrufen möchte folgendes gemacht:

Code:
                Dim dlg As mydel

                dlg = New mydel(AddressOf Registrieren.Welcome)

                dlg.Invoke()

Und in der Form Registrieren habe ich eine sub gemacht:

Code:
    Sub Welcome()
        Login.Show()

    End Sub

Er öffnet mir wie immer die Login Form,
aber dann bleibt wieder mal das ganze Programm hängen.

Ich habe jetzt mehrere versuche durch,
bitte helft mir.

Ich weiß nicht wo mein Fehler dort liegt,
ich habe noch nicht mit delegaten gearbeitet und lerne auch erst .net
daher bin ich dort noch nicht so wirklich gut drinnen.

Aber jeder Anfang ist schwer.
 
Der Code
Code:
dlg = New mydel(AddressOf Registrieren.Welcome) 
dlg.Invoke()
ist gleichwertig zum direkten Aufrufen der Welcome-Methode:
Code:
Registrieren.Welcome()
Du hast hier den Thread aber noch nicht gewechselt. Was du brauchst ist eine Referenz auf den UI-Thread, zum Beispiel eine Referenz zu einer bereits existierenden Form.
Dann rufst du die Invoke-Methode dieser existierenden Form auf. Als Parameter übergibst du ein Delegate, welcher seinerseits auf die Welcome-Methode verweist. Somit stellst du sicher, dass der UI-Thread die Welcome-Methode ausführt.
EDIT:
Folgendes könnte funktionieren (ich habe es nicht getestet, nur so hingeschrieben):
Code:
dlg = New mydel(AddressOf Registrieren.Welcome) 
Application.OpenForms.Item(0).Invoke(dlg)
Der Code ist nicht Bug-frei, da er annimmt, dass mindestens eine offene Form existiert.
Siehe auch Application.OpenForms und Item für Erklärungen der obigen Code-Zeile.
 
Zuletzt bearbeitet:
Danke,
du hast mir sehr geholfen. :D:D:D:D

Schade das man sich nicht mehrmals bedanken kann.

Ich werde mich dann auch damit mal auseinander setzen,
das ich das dann auch richtig verstehe,
was das bewirkt und wie man das richtig einsetzt.
 
Sorry das ich das Thema nochmals aufrolle,
aber ich habe das nun das nächste Problem,
das mit dem Form Aufruf funktioniert super.

Nun hänge ich am nächsten Problem,
wenn ich vom Server eine Meldung erhalte,
dann möchte ich das sie mir in einer Textbox erscheint und nicht als MessageBox.

Nun habe ich folgendes versucht:

Code:
Private Delegate Sub DAddItem(ByVal s As String)

Code:
    Private Sub AddItem(ByVal s As String)
        Textbox1.Text = s
    End Sub

Der aufruf wie er fast überall zu finden ist:
Code:
 Me.Invoke(New DAddItem(AddressOf AddItem), auswerten(1))


Da ich das ganze in ein Modul stehen habe,
da ich auf dem Thread von jeder Form zugreifen möchte funktioniert das me ja leider nicht,
ich hoffe ihr könnt mir sagen was daran wieder falsch ist.
 
Hallo,
das Problem hat sich doch dann von selbst erledigt.

Hallo,

ich habe nun ein ganz anderes Problem,
und zwar wenn ich einen Text vom Server an alle sende die verbunden sind,
dann übernimmt er mir die Zeilenumbrüche nicht,
zumindest kommen diese beim Client nicht an.

Zum Beispiel könnte der Text so aussehen:

Test

test2

test3

Dann kommt beim Client nur das Test an,
der Rest ist einfach weg.

Mein Aufruf :

Code:
SendToAllClients("server_send;" & RichTextBox1.Text)

und hier die sub dazu:

Code:
    Private Sub SendToAllClients(ByVal s As String)
        For Each c As Connection In list
            Try
                c.streamw.WriteLine(s)
                c.streamw.Flush()
            Catch
            End Try
        Next
    End Sub

Die Ausgabe beim Client habe ich mit einer Textbox, richtextbox und auch Messagebox versucht, aber es kommt nur die erste Zeile beim Client an.

Kann mir jemand sagen woran das liegt ?
 
Zuletzt bearbeitet von einem Moderator:
Was ist Conncection für eine Klasse? Schau dir mal die Dokumentation der WriteLine-Methode an, die du verwendest. Darin wird bestimmt erklärt, warum nur die erste Zeile gesendet wird.
 
Zuletzt bearbeitet:
Das ist die Methode:


Code:
    Private list As New List(Of Connection)


    Private Structure Connection
        Dim stream As NetworkStream
        Dim streamw As StreamWriter
        Dim streamr As StreamReader
        Dim user_pc_daten As String
        Dim user_name As String
    End Structure
 
Zurück