[C#]Starten nieuwe thread geeft exception op invoke

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • degroot
  • Registratie: December 2003
  • Niet online
Ik ben bezig met het leren van threads.
Alleen krijg ik constant een exception wanneer ik probeer te invoken als mijn 2e thread start,.

Vanuit de hoofdklasse(Form1.cs) , zit deze code achter een button
C#:
1
dl = new download(this, getListViewTag(), setRowNumber() - 1);


Er word dus een nieuwe download class geinitieerd , en vanuit daar word een thread gestart.

C#:
1
2
3
4
5
6
7
8
9
public download(mainForm form,string links,int rowId)
        {
            this.form = form;
            this.linkUrl = links;
            this.rowNum = rowId;
            thread = new Thread(new ThreadStart(downloadPodCast));

            thread.Start();
        }


Om mijn listviewitem op Form1.cs te updaten vanuit de draaiende thread gebruik ik dus invoke.
Bij de 1e thread die word aangemaakt, gaat dit allemaal goed, echter bij de 2e thread krijg ik een
ArgumentOutOfRangeException in onderstaande stukje code.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void DoUpdate(String message)
        {
            if (form.InvokeRequired)
            {
                // we were called on a worker thread
                // marshal the call to the user interface thread
                form.Invoke(new UpdateStatusDelegate(DoUpdate),new object[] { message });
                return;
            }

            // this code can only be reached
            // by the user interface thread
            form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message;
        }

Om dat wat duidelijker te maken heb ik een printscreen toegevoegd


http://img90.imageshack.us/my.php?image=exceptionjz5.jpg


De exception geeft dus aan dat value=2 outOfRange is , maar ik kan die Value=2 nergens uit opmaken.
Ik weet natuurlijk ook wel dat GoT'ers hier er niet zijn om te debuggen , maar dat vraag ik ook niet.
Ik wil alleen weten in welke richting ik de fout moet zoeken , of is het misschien wel een bekend iets?

Ook lopen mijn threads niet gelijk , eerst word thread 1 afgehandeld , en daarna pas thread 2.
Dat moet echter niet(Anders was er zoiets als thread.join toch?).
Waar kan dat aan liggen?
Ligt het waarschijnlijk aan het feit dat ik mijn download class verkeerd aanroep?

www.degroot-it.nl


Acties:
  • 0 Henk 'm!

  • Spiral
  • Registratie: December 2005
  • Niet online
Na invocation wordt onderstaande regel opgeroepen. Hier zoekt hij waarschijnlijk een item/subitem die niet bestaat.

C#:
1
form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message; 

To say of what is that it is not, or of what is not that it is, is false, while to say of what is that it is, and of what is not that it is not, is true. | Aristoteles


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 20:06
Spiral schreef op donderdag 29 mei 2008 @ 09:11:
Na invocation wordt onderstaande regel opgeroepen. Hier zoekt hij waarschijnlijk een item/subitem die niet bestaat.

C#:
1
form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message; 
Inderdaad, zet daar eens een breakpoint op om te zien wat er precies gebeurd.
offtopic:
Als ik jou was zou ik het nederlandse taalpakket voor .Net verwijderen. De meldingen zijn soms totaal onbegrijpelijk, en de engelse meldingen leveren veel meer resultaten in google op, mocht je eens wat op moeten zoeken.

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • Spiral
  • Registratie: December 2005
  • Niet online
degroot schreef op donderdag 29 mei 2008 @ 08:52:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void DoUpdate(String message)
        {
            if (form.InvokeRequired)
            {
                // we were called on a worker thread
                // marshal the call to the user interface thread
                form.Invoke(new UpdateStatusDelegate(DoUpdate),new object[] { message });
                return;
            }

            // this code can only be reached
            // by the user interface thread
            form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message;
        }
persoonlijk zou ik het anders noteren.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void DoUpdate(String message)
        {
            if (form.InvokeRequired)
            {
                // we were called on a worker thread
                // marshal the call to the user interface thread
                form.Invoke(new UpdateStatusDelegate(DoUpdate),new object[] { message });
            }
            else
            {
                // this code can only be reached
                // by the user interface thread
                form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message;
            }
        }


Omdat de regel in de else alleen mag/kan uitgevoerd worden als er geen invocation meer nodig is

To say of what is that it is not, or of what is not that it is, is false, while to say of what is that it is, and of what is not that it is not, is true. | Aristoteles


Acties:
  • 0 Henk 'm!

  • degroot
  • Registratie: December 2003
  • Niet online
sig69 schreef op donderdag 29 mei 2008 @ 09:44:
[...]

Inderdaad, zet daar eens een breakpoint op om te zien wat er precies gebeurd.

[...]

offtopic:
Als ik jou was zou ik het nederlandse taalpakket voor .Net verwijderen. De meldingen zijn soms totaal onbegrijpelijk, en de engelse meldingen leveren veel meer resultaten in google op, mocht je eens wat op moeten zoeken.
Als ik er een breakpoint op zet, dan krijg ik direct na het uitvoeren van de applicatie al een exception.
Dus zelfs bij het starten van de 1e thread

www.degroot-it.nl


Acties:
  • 0 Henk 'm!

  • Teunis
  • Registratie: December 2001
  • Laatst online: 01-09 21:00
degroot schreef op donderdag 29 mei 2008 @ 08:52:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void DoUpdate(String message)
        {
            if (form.InvokeRequired)
            {
                // we were called on a worker thread
                // marshal the call to the user interface thread
                form.Invoke(new UpdateStatusDelegate(DoUpdate),new object[] { message });
                return;
            }

            // this code can only be reached
            // by the user interface thread
            form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message;
        }
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void DoUpdate(String message)
        {
            if (InvokeRequired)
            {
                // we were called on a worker thread
                // marshal the call to the user interface thread
                // new object[] {message} kan ook maar zijn gewoon params dus kan ook los
                BeginInvoke(new UpdateStatusDelegate(DoUpdate), message );
                return;
            }

            // this code can only be reached
            // by the user interface thread
            form.listView2.Items[rowNum -1 ].SubItems[getColVal()].Text = message;
        }


Zelf nog nooit invoke gebruikt, alleen maar BeginInvoke, en dit werkt prima
als nog een error krijgt kun je dan je delagte posten

EDIT:
Heb net in werkende programma Invoke gebruikt en dit werkt ook prima, dus waarschijnlijk is de delegate of iets anders, dus kun je meer code laten zien zal dat wel helpen

[ Voor 6% gewijzigd door Teunis op 29-05-2008 10:21 ]

Please nerf Rock, Paper is fine. Sincerely yours, Scissor.
GW2:Teunis.6427


Acties:
  • 0 Henk 'm!

  • Spiral
  • Registratie: December 2005
  • Niet online
Dat komt waarschijnlijk doordat je 2e thread gewoon doorgaat, deze wacht niet totdat je uit gedebugged bent. Probeer maar eens de DoUpdate aan te roepen zonder dat je gebruik maakt van de threads.

To say of what is that it is not, or of what is not that it is, is false, while to say of what is that it is, and of what is not that it is not, is true. | Aristoteles


Acties:
  • 0 Henk 'm!

  • degroot
  • Registratie: December 2003
  • Niet online
Ok , ik heb het probleem gevonden , had inderdaad met de Invocation te maken.
Echter zit ik nog met 1 vraag.

Waarom worden de threads na elkaar opgevolgd? en lopen ze niet gelijktijdig?
Dat is nu dus het geval , maar ik zou ze graag allemaal tegelijk willen laten lopen.

www.degroot-it.nl


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Dat kan te maken hebben met een lock. Gebruik je een lock in je thread om toegang tot shared resources te synchroniseren?

Acties:
  • 0 Henk 'm!

  • Teunis
  • Registratie: December 2001
  • Laatst online: 01-09 21:00
BeginInvoke ipv Invoke

BeginInvoke Start ook weer een nieuwe Thread. Dit geld in C# voor meeste functies die met Begin*** beginnen

Please nerf Rock, Paper is fine. Sincerely yours, Scissor.
GW2:Teunis.6427


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:57
Persoonlijk zou ik nooit de form doorgeven aan de class waarin je thread loopt .... Dat is imho een beetje te 'tight coupled'.

Over het 'niet tegelijk lopen van je threads', is het moeilijk om er iets zinnigs over te zeggen. Hoe roep je die downloads aan ?
BeginInvoke Start ook weer een nieuwe Thread. Dit geld in C# voor meeste functies die met Begin*** beginnen
De Begin*** methods zijn asynchrone versies van die methods; maar het gebruiken van de synchrone versie om een event te raisen of om iets aan te passen, zou niet mogen verhinderen dat 2 threads tegelijkertijd lopen.

[ Voor 39% gewijzigd door whoami op 29-05-2008 10:28 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • degroot
  • Registratie: December 2003
  • Niet online
bigbeng schreef op donderdag 29 mei 2008 @ 10:24:
Dat kan te maken hebben met een lock. Gebruik je een lock in je thread om toegang tot shared resources te synchroniseren?
Nope, gebruik ik nergens
whoami schreef op donderdag 29 mei 2008 @ 10:26:
Over het 'niet tegelijk lopen van je threads', is het moeilijk om er iets zinnigs over te zeggen. Hoe roep je die downloads aan ?
Ik doe dat doormiddel van onderstaande code, maar nu ik die nog eens nakijk , denk ik de fout gevonden te hebben.


Komt het misschien door de while loop die steeds mijn form update? of kan het daar niet aan liggen?
C#:
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
public download(mainForm form,string links,int rowId)
        {
            this.form = form;
            this.linkUrl = links;
            this.rowNum = rowId;
           
            thread = new Thread(new ThreadStart(downloadPodCast));
            thread.Start();
        }

        private void downloadPodCast()
        {
            using (WebClient wcDownload = new WebClient())
            {
                try
                {
                    // Create a request to the file we are downloading 
                    webRequest = (HttpWebRequest)WebRequest.Create(linkUrl);

                    // Retrieve the response from the server 
                    webResponse = (HttpWebResponse)webRequest.GetResponse();
                    // Ask the server for the file size and store it 
                    Int64 fileSize = webResponse.ContentLength;

                    // Open the URL for download 
                    strResponse = wcDownload.OpenRead(linkUrl);
                    // Create a new file stream where we will be saving the data (local drive) 
                    try
                    {
                        strLocal = new FileStream(@"c:\" + form.listViewName + " - " + form.colValue + ".mp3", FileMode.Create, FileAccess.Write, FileShare.None);
                    }
                    catch (DirectoryNotFoundException)
                    {
                        //Directory.CreateDirectory(downloadFolder);
                        //strLocal = new FileStream(downloadFolder + title + "_-_" + desc + "_-_" + date + ".mp3", FileMode.Create, FileAccess.Write, FileShare.None);

                    }
                    // It will store the current number of bytes we retrieved from the server 
                    int bytesSize = 0;
                    // A buffer for storing and writing the data retrieved from the server 
                    byte[] downBuffer = new byte[10000];

                    // Loop through the buffer until the buffer is empty 
                    while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                        // Write the data from the buffer to the local hard drive 
                        strLocal.Write(downBuffer, 0, bytesSize);
                        // Invoke the method that updates the form's label and progress bar 
                        long kbLength = strLocal.Length / 1024;
                        long kbFile = fileSize / 1024;
                        percentcomplete = Convert.ToInt32(strLocal.Length * 100 / fileSize);
                        if (percentcomplete != 100)
                        {
                            setColVal(4);
                            DoUpdate(Convert.ToString(kbLength) + "kb of " + Convert.ToString(kbFile) + "kb (" + Convert.ToString(percentcomplete) + "%)");                            
                        }
                        else
                        {
                            setColVal(3);
                            DoUpdate("completed");
                            setColVal(4);
                            DoUpdate(Convert.ToString(kbLength) + "kb of " + Convert.ToString(kbFile) + "kb (" + Convert.ToString(percentcomplete) + "%)");                            
                        }
                    }
                }
                finally
                {
                    // When the above code has ended, close the streams 
                    webResponse.Close();
                    strResponse.Close();
                    strLocal.Close();
                }
            }
        }

[ Voor 90% gewijzigd door degroot op 29-05-2008 10:30 ]

www.degroot-it.nl


Acties:
  • 0 Henk 'm!

  • degroot
  • Registratie: December 2003
  • Niet online
iemand nog? en dan met betrekking van het niet gelijk lopen van threads?

www.degroot-it.nl

Pagina: 1