Ορίστε, να έχεις δουλειά να κάνεις και να πέφτουν τέτοια ενδιαφέροντα posts…
Λοιπόν, δεν πρόλαβα να δω καλά τον κώδικά σου, αλλά γενικά υπάρχουν συνήθως δύο πράγματα που μας ενδιαφέρουν όταν παίζουμε με τα threads.
Το πρώτο είναι αν θέλουμε να ενημερώνουμε τις τιμές των controls μιας φόρμας μέσα από ένα άλλο thread. Γενικά, οι φόρμες είναι σχεδιασμένες να δουλεύουν single-threaded όπερ σημαίνει ότι ο χρυσός κανόνας είναι «Πάντοτε πειράζουμε τα controls μόνο μέσα από το thread που ανήκουν (αυτό της φόρμας που τα δημιούργησε)». Αν δεν το κάνουμε, στην περίπτωση που απλά διαβάζουμε τα properties τους δεν δημιουργείται μεγάλο πρόβλημα, ωστόσο, μεγάλα projects γράφουμε, πολλές σκοτούρες έχουμε, είναι θέμα χρόνου πότε θα το ξεχάσουμε/μπερδέψουμε/__________ (συμπλήρωσε το κενό) και θα κάνουμε ανάθεση σε property. Για να αποφύγουμε λοιπόν αυτό το πρόβλημα, που όπως όλοι ξέρουμε είναι ό,τι χειρότερο μπορεί να σου τύχει σε debugging, η λύση είναι μία:
Κάθε control έχει ένα property που λέγεται InvokeRequired (ανήκει στην κλάση Control) το οποίο επιστρέφει True αν το τρέχον thread που το κάνει access δεν είναι το thread που δημιούργησε το control. Οπότε, ρωτάμε, και αν είναι True, τότε καλούμε την Invoke μέθοδο του control χρησιμοποιώντας ένα delegate και ενδεχομένως ένα parameter array τύπου Object. Το μυστικό είναι ότι το control χρησιμοποιεί το delegate για να καλέσει τη μέθοδο στο context του δικού του thread!
Το δεύτερο πράγμα που μας ενδιαφέρει είναι αν θέλουμε να μας επιστρέφονται τιμές από το thread το οποίο δημιουργήσαμε. Για να γίνει κάτι τέτοιο, χρειάζεται να ξέρουμε πότε τελείωσε το thread οπότε σε αυτή την περίπτωση μπορούμε είτε να δουλέψουμε με Raise Event ή με delegates για να περάσουμε τιμές σε κάποια συγκεκριμένη μέθοδο όταν τελειώσει το thread. Εδώ και πάλι χρειάζεται προσοχή όπως παραπάνω σχετικά με το αν πρέπει να πειράξουμε controls γιατί οι event handlers τρέχουν στο context του thread που έκανε raise το event.
Vir prudens non contra ventum mingit