Toon posts:

[VB.net] data uit een klasse door te geven aan form

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik probeer data uit een klasse door te geven aan mijn form. Het lijkt mij dat dit ik dit bijvoorbeeld zo moet doen: form1.RichTextBox1.Text = "bla bla".

ik heb de volgende werkende code:
code:
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
class form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Try
            Curl.GlobalInit(CURLinitFlag.CURL_GLOBAL_ALL)

            dnsLock = New Object()
            cookieLock = New Object()

            Dim share As Share
            share = New Share()
            Dim lf As Share.LockFunction, ulf As Share.UnlockFunction
            lf = New Share.LockFunction(AddressOf OnLock)
            ulf = New Share.UnlockFunction(AddressOf OnUnlock)
            share.SetOpt(CURLSHoption.CURLSHOPT_LOCKFUNC, lf)
            share.SetOpt(CURLSHoption.CURLSHOPT_UNLOCKFUNC, ulf)
            share.SetOpt(CURLSHoption.CURLSHOPT_SHARE, _
                CURLlockData.CURL_LOCK_DATA_COOKIE)
            share.SetOpt(CURLSHoption.CURLSHOPT_SHARE, _
                CURLlockData.CURL_LOCK_DATA_DNS)

            Dim t1 As Thread, t2 As Thread
            et1 = New EasyThread("http://www.google.nl", share)
            et2 = New EasyThread("http://www.google.com", share)

            t1 = New Thread(New ThreadStart(AddressOf et1.ThreadFunc))
            t2 = New Thread(New ThreadStart(AddressOf et2.ThreadFunc))
            t1.Start()
            t2.Start()

            t1.Join()
            t2.Join()

            share.Cleanup()
            Curl.GlobalCleanup()
        Catch ex As Exception
            Console.WriteLine(ex)
        End Try
end class

Public Class EasyThread
    Private Shared wf As Easy.WriteFunction
    Private url As String
    Private share As Share

    Shared Sub New()
        wf = New Easy.WriteFunction(AddressOf OnWriteData)
    End Sub

    Public Sub New(ByVal s As String, ByVal shr As Share)
        Debug.WriteLine("EasyThread instance constructor: url={0}", s)
        url = s
        share = shr
    End Sub

    Public Sub ThreadFunc()
        Dim easy As Easy
        easy = New Easy()
        easy.SetOpt(CURLoption.CURLOPT_URL, url)
        easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf)

        easy.Perform()
        easy.Cleanup()
    End Sub

    'als er data van curl terug komt
    Public Shared Function OnWriteData(ByVal buf() As Byte, ByVal size As Int32, ByVal nmemb As Int32, ByVal extraData As Object) As Int32
        Form1.RichTextBox1.Text = Form1.RichTextBox1.Text & System.Text.Encoding.UTF8.GetString(buf)
        'Return size * nmemb
    End Function

End Class


Met deze code haal ik de html codes van twee websites te gelijk op. Als curl een reactie voor mij heeft word de Public Shared Function OnWriteData uitgevoerd.
dit werkt allemaal prima want als ik bijvoorbeeld in Public Shared Function OnWriteData dit neerzet debug.writeline(System.Text.Encoding.UTF8.GetString(buf), krijg ik de html in mijn debug scherm.
maar ik krijg het maar niet in mijn RichTextBox... Wie ziet waar het fout gaat of hoe ik dit zou kunnen oplossen?

Verwijderd

Topicstarter
ik heb het als volgt weten op te lossen:

in form1
code:
1
2
3
4
5
    Public Shared Tbox As RichTextBox

    Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Tbox = RichTextBox1
    End Sub


in de onwritedata functie:
Control.CheckForIllegalCrossThreadCalls = False
Form1.Tbox.Text = Form1.Tbox.Text & System.Text.Encoding.UTF8.GetString(buf)

Dit zal waarschijnlijk geen goede oplossing zijn, maar voor nu werkt het ieder geval. Als iemand wat beters weet hoor ik het graag!

  • CodeIT
  • Registratie: Juni 2002
  • Laatst online: 17:12

CodeIT

Code IT

Vanuit thread 1 mag je inderdaad geen controls van thread 2 aanpassen. Hiervoor hebben ze delegates bedacht.
Tutorial: http://www.devx.com/getHelpOn/10MinuteSolution/20365

Verwijderd

Topicstarter
Ik kom er toch niet helemaal uit... Ik heb het volgende:

Class EasyThread:
code:
1
2
3
4
5
6
7
Private Delegate Sub MyDelSub(ByVal strTest As String)

    Public Function OnWriteData(ByVal buf() As Byte, ByVal size As Int32, ByVal nmemb As Int32, ByVal extraData As Object) As Int32
        Dim del As MyDelSub
        del = New MyDelSub(AddressOf Form1.WriteToForm)
        del.Invoke(System.Text.Encoding.UTF8.GetString(buf))
    End Function


Dan heb ik in class Form1:
code:
1
2
3
    Public Sub WriteToForm(ByVal strTest As String)
        Tbox.Text = strTest
    End Sub


Ik krijg dan de fout:
Cross-thread operation not valid: Control 'RichTextBox1' accessed from a thread other than the thread it was created on.

Wat gaat er fout? Hoe kan ik dit oplossen?

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Maak je gebruik van VB.NET 2005 ? Zoja, waarom gebruik je dan geen backgroundworker ?
Indien je niet gebruikt maakt van .NET 2.0, kijk dan eens naar het 'Task pattern'. (ff zoeken op GoT met deze searchstring, dan kom je wel iets tegen)

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik heb een backgroundworker

code:
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
    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Try
            Curl.GlobalInit(CURLinitFlag.CURL_GLOBAL_ALL)

            dnsLock = New Object()
            cookieLock = New Object()

            Dim share As Share
            share = New Share()
            Dim lf As Share.LockFunction, ulf As Share.UnlockFunction
            lf = New Share.LockFunction(AddressOf OnLock)
            ulf = New Share.UnlockFunction(AddressOf OnUnlock)
            share.SetOpt(CURLSHoption.CURLSHOPT_LOCKFUNC, lf)
            share.SetOpt(CURLSHoption.CURLSHOPT_UNLOCKFUNC, ulf)
            share.SetOpt(CURLSHoption.CURLSHOPT_SHARE, _
                CURLlockData.CURL_LOCK_DATA_COOKIE)
            share.SetOpt(CURLSHoption.CURLSHOPT_SHARE, _
                CURLlockData.CURL_LOCK_DATA_DNS)

            Dim t1 As Thread, t2 As Thread
            et1 = New EasyThread("http://www.google.com", share, AddressOf ThreadCompleted)
            et2 = New EasyThread("http://www.google.nl", share, AddressOf ThreadCompleted)


            t1 = New Thread(New ThreadStart(AddressOf et1.ThreadFunc))
            t2 = New Thread(New ThreadStart(AddressOf et2.ThreadFunc))
            t1.Start()
            t2.Start()

            t1.Join()
            t2.Join()

            share.Cleanup()
            Curl.GlobalCleanup()
        Catch ex As Exception
            Console.WriteLine(ex)
        End Try
    End Sub


Dat heeft toch niets te maken met die data die ik terug wil krijgen?
Ik zal kijken naar die Task pattern.

[ Voor 3% gewijzigd door Verwijderd op 13-09-2006 11:16 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Backgroundworker implementeert het task-pattern.
Backgroundworker zorgt ervoor dat -als je het op een goede manier gebruikt- je die Cross Thread Operation exceptions niet krijgt, doordat de method die je wilt uitvoeren (die een control aanpast die op de UI thread gecreeërd werd), 'invoked' zodanig dat die method ook op de UI thread uitgevoerd wordt.

Waarom execute je trouwens nog eens dingen op een andere thread binnen je backgroundworker ? Het kan aan mij liggen, maar ik zie er het nut niet van in.

Je koppelt je ene class trouwens volledig aan je Form door je manier van werken. Maak een event in je class die gefired wordt als er data binnenkomt, en hang in je form een eventhandler aan die event.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Dus met die Backgorundworker kan ik alle functionaliteit van class EasyThread in het form zetten? En dan zou ik dus voor iedere thread een backgorundworker aanmaken?

Verwijderd

Topicstarter
Ik heb aan de hand van de pagina http://www.vbip.com/books/1861007167/chapter_7167_05.asp
eventshandlers gebruikt.
Als ik als event MsgBox gebruik gaat het goed , maar als ik: Tbox.Text = Tbox.Text & Data krijg ik weer de:
Cross-thread operation not valid: Control 'RichTextBox1' accessed from a thread other than the thread it was created on.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Je moet je eventhandler dan ook niet direct aanroepen, maar de methods die eraan hangen invoken.

whoami in "\[C#] button.Show() vanuit anderen Thread"
whoami in "\[C#] Communicatie tussen classes"

:z

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik heb dan nu in mijn form
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Private WithEvents et1 As EasyThread
    Private WithEvents et2 As EasyThread

    Private Delegate Sub MyDelSub(ByVal data As String)

    Private Sub opOntvangen(ByVal Data As String) Handles et2.data_ontvangen
        'MsgBox(Data)
        Dim del As MyDelSub
        del = New MyDelSub(AddressOf testje)
        del.Invoke(Data)
    End Sub

    Public Sub testje(ByVal Data As String)
        Tbox.Text = Data
    End Sub


in class EasyThread
code:
1
2
3
4
5
6
    Public Event data_ontvangen(ByVal Data As String)

   Public Function OnWriteData(ByVal buf() As Byte, ByVal size As Int32, ByVal nmemb As Int32, ByVal extraData As Object) As Int32
        RaiseEvent data_ontvangen(System.Text.Encoding.UTF8.GetString(buf))
        Return size * nmemb
    End Function


Krijg nog steeds dezelfde fout. Please help, heb geen idee wat ik moet doen
Pagina: 1