Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

ερώτηση σχετικά με το threading

Îåêßíçóå áðü ôï ìÝëïò zaxos. Τελευταία δημοσίευση από το μέλος Aris στις 20-10-2005, 18:26. Υπάρχουν 12 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  18-10-2005, 12:30 6233

    Lightning [li] ερώτηση σχετικά με το threading

    καλησπέρα.

    Είμαι καινούργιος στην ανάπτυξη λογισμικού χρησιμοποιώντας το dotnet γι' αυτό πιθανόν η ερώτηση μου να σας φανεί εύκολη.

    Εχω μια κεντρική mdi φόρμα απ'την οποία καλώ άλλες φόρμες.Η μία απο αύτες χρείαζεται λίγα λεπτά να φορτώσει λόγω μεγάλου αριθμού δεδομένων.Στη διάρκεια της φόρτωσης η εφάρμογη μοιάζει σαν να μην ανταποκρίνεται, χάνονται τα μενού και τα toolbar κάτι που φυσικά θα είναι πολύ ενοχλητικό για τον χρήστη.Μετά απο λίγο ψάξιμο κατέληξα ότι μάλλον πρέπει να χρησιμοποιήσω threading αλλά δεν το κατάφερα.

    θα εκτιμήσω την οποιαδήποτε βοήθεια.

     

     

     

  •  18-10-2005, 14:11 6236 σε απάντηση της 6233

    Απ: ερώτηση σχετικά με το threading

    Καλησπέρα και καλώς ήλθες!

    Δεν είμαι σιγουρος οτι πρέπει να χρησιμοποιήσεις threading όσον αφορά στην κλήση των φορμών. Και αυτό γιατί υπάρχουν ένα σωρό προβλήματα που σχετίζονται με φόρμες που καλούνται / ελέγχονται από διαφορετικά threads. Γενικά, ένας εμπειρικός κανόνας είναι οτι οι φόρμες πρεπει να καλούνται και να διαχειρίζονται από το main thread (της ίδιας της εφαρμογής).

    Βεβαια, δεν σε εμποδίζει κανείς να βάλεις τις διαδικασίες οι οποίες πραγματικά δημιουργούν την καθυστέρηση σε ένα δικό τους thread (π.χ. την φόρτωση των δεδομένων από database), δεδομένου όμως οτι αυτές οι διαδικασίες δεν θα επιχειρήσουν να αλλάξουν τιμές στα controls οποιασδήποτε φόρμας. Αλλιώς, το πρόβλημα είναι ίδιο με το παραπάνω.

    Δοκίμασα κάτι πολύ πρόχειρο όμως το οποίο θα μπορούσε ίσως να σε βοηθήσει, και αν κάποιος άλλος συνάδελφος μπορεί να δώσει ακόμα καλύτερο παράδειγμα, please do.

    'Εδώ έχουμε τον έλεγχο του κλικ σε ένα μενού
        'που φορτώνει τη μισητή φόρμα που κάνει χρόνια να ανοίξει.
        Private Sub MenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem3.Click


            'Ας βάλουμε κλεψυδρούλα
            Me.Cursor = System.Windows.Forms.Cursors.WaitCursor



            'Απ, τι ειναι αυτό; Μια νέα φορμούλα "παρακαλώ περιμένετε"
            'για να μην αναρωτιόμαστε τι κάνει το δαιμονισμένο παλιομηχάνημα.


            Dim w As New frmWait    'Φτιάχτην
            w.TopMost = True        'Ναι, γιατί αλλιώς δεν θα τη δούμε ποτέ. :)
            w.Show()                'Δείχτην


            'Εδώ θέλω βοήθεια αν κανείς έχει να προτείνει κάτι καλύτερο.
            'Βασικά πρέπει να του δώσουμε τον απαιτούμενο χρόνο να κάνει render τη φορμα
            'Me thread.sleep δεν έχουμε καλό αποτέλεσμα, και εγω τώρα είμαι πολύ
            'ζαλισμένος για να σκεφτώ κάτι καλύτερο.
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()


            'Ωραία. Τωρα έχουμε μπροστα μπροστα τη φόρμα "Παρακαλώ περιμένετε" και
            'την κλεψύδρα μας...ας φορτώσουμε τωρα την κανονική και ας κάνει όση ώρα θέλει.
            Dim b As New Form2
            b.MdiParent = Me
            b.Show()


            'Τώρα κλείστα όλα τα "περιμένετε"
            w.Hide()
            w.Close()
            w = Nothing


            'Ας πάμε και τον δρομέα στην κανονική του μορφή
            Me.Cursor = System.Windows.Forms.Cursors.Default


        End Sub

    Αυτή βέβαια η προσέγγιση έχει δύο προβλήματα:

    1. Δεν μας αφήνει ελεύθερη τη μετακίνηση στην κύρια φόρμα
    2. Αν επιχειρήσεις να κουνήσεις οτιδήποτε, θα δείς πάλι χαλασμένα εικονιδιάκια.

    Γι'αυτό και την αναφέρω σαν πρόχειρο παράδειγμα, όχι ως λύση.

     


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  18-10-2005, 15:42 6240 σε απάντηση της 6233

    Απ: ερώτηση σχετικά με το threading

    Θα μπορούσες να πάρεις ιδέες από ένα παρόμιο προβληματισμό σε αυτή τη συζήτηση: Φόρμα "Please wait" κατά την εκτέλεση απαιτητικής σε χρόνο διαδικασίας.

     

    George J.

     


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
  •  18-10-2005, 16:43 6243 σε απάντηση της 6240

    Απ: ερώτηση σχετικά με το threading

    Αχμ, ναι, εγώ την είχα ξεκινήσει αυτή τη συζήτηση! Αλλά εκεί μιλάει για το πώς ενημερώνεις τη φόρμα please wait κατά τη διάρκεια της διαδικασίας ωστε να μην φαίνεται "ακίνητη"...δεν ειναι το ίδιο πρόβλημα, έχει όμως αρκετά στοιχεία που θα μπορούσαν να βοηθήσουν το συνάδελφο, αρα συμφωνώ.
    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  18-10-2005, 20:49 6246 σε απάντηση της 6236

    Απ: ερώτηση σχετικά με το threading

     cap wrote:

            'Εδώ θέλω βοήθεια αν κανείς έχει να προτείνει κάτι καλύτερο.
            'Βασικά πρέπει να του δώσουμε τον απαιτούμενο χρόνο να κάνει render τη φορμα
            'Me thread.sleep δεν έχουμε καλό αποτέλεσμα, και εγω τώρα είμαι πολύ
            'ζαλισμένος για να σκεφτώ κάτι καλύτερο.
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()
            Application.DoEvents() : Application.DoEvents() : Application.DoEvents()

    Big Smile [:D]Big Smile [:D]Big Smile [:D] Είσαι τελείως απαράδεκτος!!!


    Vir prudens non contra ventum mingit
  •  19-10-2005, 01:08 6250 σε απάντηση της 6246

    Απ: ερώτηση σχετικά με το threading

    Χαχα, ναι! :) Αλλα δεν ειδα εναλλακτικές! :)

    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  19-10-2005, 13:14 6257 σε απάντηση της 6250

    Απ: ερώτηση σχετικά με το threading

    Cool [H]Να, ορίστε μια εναλλακτική :

        for (int i=0; i<9; i++) Application.DoEvents();

    Το ξέρω, το ξέρω είμαι μεγαλοφυια Big Smile [:D]Big Smile [:D]Big Smile [:D]


    Στερνή μου γνώση να σε είχα πρώτα...
  •  19-10-2005, 18:48 6264 σε απάντηση της 6233

    Απ: ερώτηση σχετικά με το threading

    Εάν βάλεις ένα w.Update() μετά το w.Show(), δεν θα την δείξει;

    Άρης
    Aris
  •  19-10-2005, 19:16 6266 σε απάντηση της 6264

    Απ: ερώτηση σχετικά με το threading

    Αν εκεί που δουλεύετε πάρει φωτιά το PC, θα είναι τιμωρία από τον θεό της πληροφορικής βρε αθεόφοβοι Lightning [li] (cap και kkara)!

     

    Λοιπόν, για να σοβαρευτούμε λίγο… Το να βάλεις τόσα Application.DoEvents, όσα απαιτούνται για να προλάβει να σχεδιαστεί η φόρμα είναι τουλάχιστον μπακαλίστικο! Υπάρχουν άλλοι κομψότεροι τρόποι, όπως τα threads αλλά και άλλοι κομψότατοι τρόποι όπως τα delegates. Τα τελευταία μάλιστα στο VS2005 μας παρέχονται και σε μορφή component για όσους τους αρέσει το κλίκι-κλίκι…

     

    Όπως και να έχει, το ερώτημα είναι (όπως πάντοτε άλλωστε) «τι θέλω να κάνω;». Δηλαδή, ας υποθέσουμε ότι έχουμε μια φόρμα που απαιτεί κάποια ώρα για να σηκωθεί. Βεβαίως, βεβαίως μπορούμε να πάρουμε το κομμάτι του κώδικα που ευθύνεται και να το βάλουμε να τρέξει, με κάποιο τρόπο, παράλληλα ώστε να ελαφρύνει η φόρμα. Το θέμα είναι, μέχρι να ολοκληρωθεί αυτό το lro (long-running-operation), ο χρήστης τι κάνει; Μπορεί να κάνει κάτι άλλο; Ή μήπως είναι καταδικασμένος, προκειμένου να μπορέσει να δουλέψει, να περιμένει να τελειώσει το lro? Zaxos, υποθέτω ότι αυτό είναι το σενάριο σου… Σε αυτήν τη δεύτερη περίπτωση, αυτό που θα πρέπει υποχρεωτικά να κάνουμε είναι να εμφανίσουμε την please-wait φόρμα.

     

    Μιας και όταν τα λέγαμε αυτά στο Φορμα "Please wait" κατά την εκτέλεση απαιτητικής σε χρόνο διαδικασίας, ο cap τα ξέχασε Stick out tongue [:P], ας δούμε λοιπόν, τι επιλογές έχουμε για να υλοποιήσουμε ένα fetch-data-and-populate-control σενάριο…

     

    Έχουμε μια φόρμα και θέλουμε να κάνουμε populate ένα listbox με data. O κώδικας που μας επιστρέφει τα data είναι ο παρακάτω:

     

        Function GetCustomerList(ByVal State As String) As String()

            '*** call across network to DBMS or Web Services to retrieve data

            '*** pass data back to caller using string array return value

            Threading.Thread.CurrentThread.Sleep(3000)

     

            Return "1000,1001,1002,1003".Split(",")

        End Function

     

    Επίσης, θα χρειαστούμε ένα delegate object δηλωμένο σε επίπεδο κλάσης (φόρμας):

     

        Delegate Function GetCustomerListHandler(ByVal State As String) As String()

     

    Η παράμετρος state στο function δεν χρησιμοποιείται αλλά την έχω βάλει μόνο για να δείτε πως μπορούμε να περνάμε και παραμέτρους κατά τις ασύγχρονες κλήσεις.

     

    1η επιλογή: Σύγχρονο fetch

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            '*** create delegate object and bind to target method

            Dim handler1 As GetCustomerListHandler

            handler1 = AddressOf GetCustomerList

     

            '*** execute method synchronously

            Dim retval As String()

            retval = handler1.Invoke("dummy")

     

            ListBox1.Items.AddRange(retval)

        End Sub

     

    Θα μου πείτε, γιατί να το κάνουμε έτσι, αφού θα μπορούσαμε να πούμε

     

            ListBox1.Items.AddRange(GetCustomerList)

     

    Πράγματι, ο κώδικας είναι ισοδύναμος ως προς το αποτέλεσμα, αλλά ο λόγος είναι απλά για να εξοικιωθούμε με τα delegates και επίσης να δούμε πως το ίδιο delagate object εξυπηρετεί πολλαπλούς τρόπους κλήσης (sync/async). Αν δεν έχετε ξαναδεί delegate θα σας φανεί λίγο περίεργο, δηλαδή να δηλώνουμε Delegate Function GetCustomerListHandler {…} και κατόπιν Dim handler1 As GetCustomerListHandler. Απλά φαναστείτε ότι με το πρώτο, ορίζουμε έναν τύπο από delegate. Είναι σαν να λέμε:

     

        Private Enum WeatherEnum

            Sunny

            Cloudy

            Rainy

        End Enum

     

        Private myWeather As WeatherEnum

     

    με τη διαφορά ότι στα delegates ορίζουμε και instance ταυτόχρονα!

     

    2η επιλογή: Ασύγχρονα delegates με polling

     

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

            '*** create delegate object and bind to target method

            Dim handler1 As GetCustomerListHandler = AddressOf GetCustomerList

     

            '*** execute method asynchronously

            Dim ar As System.IAsyncResult

            ar = handler1.BeginInvoke("dummy", Nothing, Nothing)

     

            Timer1.Enabled = True

     

            ' Do whatever you have to do

     

            'check to see if the async call has completed before continue

            Do

                Application.DoEvents() '

            Loop Until ar.IsCompleted

     

            Timer1.Enabled = False

     

            Dim retval As String()

            Try

                'if you ommit the loop above, the EndInvoke looks like a blocking call

                retval = handler1.EndInvoke(ar)

                ListBox1.Items.AddRange(retval)

            Catch ex As Exception

                Debug.WriteLine(ex.Message)

            End Try

        End Sub

     

    Αυτήν τη φορά, αντί για Invoke, καλούμε την BeginInvoke του delegate. Παρατηρήστε ότι περνάμε στην παράμετρο state την τιμή “dummy” , ενώ η χρησιμότητα των δύο nothing παραμέτρων θα φανεί παρακάτω. Το σενάριο εδώ λέει, «ξεκίνα να τρέχεις παράλληλα το function, εγώ έχω λίγη δουλειά να κάνω, αν τελειώσω, πέφτω σε loop μέχρει να τελειώσεις κι εσύ». Οι πληροφορίες για το σε τι κατάσταση βρίσκεται η εκτέλεση του delegate βγαίνουν μέσα από το IAsyncResult το οποίο μας δίνει πρόσβαση στο IsCompleted property και την μέθοδο EndInvoke. Όλο το ζουμί είναι εκεί. Μέχρι να την καλέσουμε, δεν παίρνουμε πίσω αποτελέσματα, ενώ αν την καλέσουμε νωρίτερα (πριν να ολοκληρωθεί), έχουμε ένα blocking call (πέφτουμε στην 1η περίπτωση). Αυτό το σενάριο είναι κατάλληλο για υλοποίηση wait-form.

     

    3η επιλογή: Callback delegates

     

    Εδώ αρχίζουν τα ενδιαφέροντα…

     

        '*** create delegate object to execute method asynchronously

        Private TargetHandler1 As GetCustomerListHandler = AddressOf GetCustomerList

     

        '*** create delegate object to service callback from CLR

        Private CallbackHandler1 As AsyncCallback = AddressOf MyCallbackMethod1

     

    Ορίζουμε ένα νέο delegate object, καθως επίσης κι ένα AsyncCallback delegate. Αυτό το δεύτερο είναι ένα ειδικό delegate το οποίο σχετίζεται με ένα function (MyCallbackMethod1) το οποίο θα τρέξει, όταν ολοκληρωθεί το invocation.

     

        Sub cmdExecuteTask1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button3.Click

            '*** execute method asynchronously with callback

            TargetHandler1.BeginInvoke("dummy", CallbackHandler1, Nothing)

            Timer1.Enabled = True

        End Sub

     

    Παρατηρείστε ότι αυτήν τη φορά με το BeginInvoke περνάμε και ως παράμετρο το AsyncCallback delegate.

     

        '*** callback method runs on worker thread and not the UI thread

        Sub MyCallbackMethod1(ByVal ar As IAsyncResult)

            '*** this code fires at completion of each asynchronous method call

            Dim retval As String()

            retval = TargetHandler1.EndInvoke(ar)

            '  **********************************************************************************************

            ListBox1.Items.AddRange(retval) 'This is illegal... UI should not be updated from async threads!

            '  **********************************************************************************************

            Timer1.Enabled = False

        End Sub

     

    Και εδώ πλέον κάνουμε handle τα αποτελέσματα από την ασύγχρονη εκτέλεση. Εδώ είναι ένα σημείο που χρειάζεται προσοχή! Αν αυτό που γίνεται είναι κάτι που γίνεται στο background, όσο συνεχίζει να δουλεύει ο χρήστης, και μετά απλώς τελειώνει τότε έχει καλώς. Αν όμως, ανάλογα των αποτελεσμάτων, αποφασίσουμε να κάνουμε δίαφορες ενέργειες στο UI, τότε ο κώδικας (όπως παραπάνω, που καλούμε την AddRange(retval)) είναι ακατάλληλος. Γιατί, αυτό το function (MyCallbackMethod1) μπορεί να συνυπάρχει οπτικά μαζί με τον υπόλοιπο κώδικα της φόρμας, εντούτoις εκτελείται, όταν έρθει η ώρα, σε διαφορετικό thread και όπως έχουμε πει ΤΑ CONTROLS TA ΠΕΙΡΑΖΟΥΜΕ ΜΟΝΟ ΜΕΣΑ ΑΠΟ ΤΟ THREAD ΣΤΟ ΟΠΟΙΟ ΑΝΗΚΟΥΝ. Γι αυτόν το λόγο, έχουμε την τέταρτη και τελευταία υλοποίση του σεναρίου.

     

    4η επιλογή: Callback delegates με UI update

     

    Εδώ θα αλλάξουμε λίγο το παράδειγμά μας και θα υποθέσουμε ότι τα data μας τα επιστρέφει ένα object που έχει αναλάβει το data access και η μέθοδος που καλούμε είναι η εξής:

     

    Public Function GetAllCustomers() As DataTable

     

    Άρα χρειαζόμαστε

     

       '*** a delegate for executing handler methods

        Delegate Function GetAllCustomersHandler() As DataTable

     

    Να δηλώσουμε ένα νέο delegate object, κατάλληλο για να διαχειριστεί το signature του GetAllCustomers

     

     

        '*** create delegate object to execute method asynchronously

        Private TargetHandler2 As GetAllCustomersHandler = AddressOf oCustomers.GetAllCustomers

     

    Να ορίσουμε ένα delegate, τύπου GetAllCustomersHandler, το οποίο θα ξεκινήσει τη διαδικασία

     

        '*** create delegate object to service callback from CLR

        Private CallbackHandler2 As AsyncCallback = AddressOf MyCallbackMethod2

     

    Να ορίσουμε ένα δεύτερο delegate object το οποίο θα τρέξει τον κώδικα που θα εκτελεστεί όταν τελειώση η διαδικασία.

     

        '*** delegate used to switch control over to primary UI thread

        Delegate Sub UpdateUIHandler(ByVal StatusMessage As String, ByVal dtCustomers As DataTable)

     

    Και τέλος, ένα τρίτο delegate το οποίο θα μας επιτρέψει να χειριστούμε τα data στο UI από όπου όλα ξεκίνησαν.

     

    Ο αντίστοιχος κώδικας έχει ως εξής:

     

       Sub cmdExecuteTask_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click

            '*** execute method asynchronously with callback

            UpdateUI("Starting task...", Nothing)

            TargetHandler2.BeginInvoke(CallbackHandler2, Nothing)

        End Sub

     

    Όπως προηγουμένως. Απλά πλέον χρησιμοποιούμε μια ρουτίνα UpdateUI για να ενημερώσουμε το UI.

     

        '*** callback method runs on worker thread and not the UI thread

        Sub MyCallbackMethod2(ByVal ar As IAsyncResult)

            Try

                Dim retval As DataTable

                retval = TargetHandler2.EndInvoke(ar)

                UpdateUI("Task complete", retval)

            Catch ex As Exception

                Dim msg As String

                msg = "Error: " & ex.Message

                UpdateUI(msg, Nothing)

            End Try

        End Sub

     

    Κι εδώ όπως προηγουμένως, μόνο που περνάμε τα αποτελέσματα στην UpdateUI.

    Το μεγάλο ερώτημα είναι τι γίνεται στην UpdateUI…

     

        '*** can be called from any method on form to update UI

        Sub UpdateUI(ByVal StatusMessage As String, ByVal dtCustomers As DataTable)

            '*** check to see if thread switch is required

            If Me.InvokeRequired Then

                Dim handler As New UpdateUIHandler(AddressOf UpdateUI_Impl)

                Dim args() As Object = {StatusMessage, dtCustomers}

                Me.BeginInvoke(handler, args)

            Else

                UpdateUI_Impl(StatusMessage, dtCustomers)

            End If

        End Sub

     

        '*** this method always runs on primary UI thread

        Sub UpdateUI_Impl(ByVal StatusMessage As String, ByVal Customers As DataTable)

            Label1.Text = StatusMessage

            ListBox1.DataSource = Customers

        End Sub

     

    Τσα! Ουσιαστικά, η δουλειά δεν γίνεται ακριβώς στην UpdateUI. Απλώς η UpdateUI ελέγχει από πού έρχεται αυτός που την καλεί. Αν έρχεται από διαφορετικό thread (InvokeRequired=true), τότε μέσω του UpdateUIHandler, επιστρέφουμε στο thread του UI και καλούμε την UpdateUI_Impl.

     

    Με αυτά τα ολίγα έχουν καλυφθεί τέσσερα σενάρια περί fetch-data-and-populate-control. Aν υπάρχει κανένα πρόβλημα ή ερώτημα μπορούμε να συνεχίσουμε την κουβέντα μας…

     


    Vir prudens non contra ventum mingit
  •  19-10-2005, 21:23 6270 σε απάντηση της 6266

    Απ: ερώτηση σχετικά με το threading

    Δεν έχω παρά να χειροκροτήσω και να βάλω άνετα ένα πενταράκι βαθμολογία στο συγκεκριμένο! Μανο, πολύ καλή δουλειά! (Και χρήσιμη, και για μένα και για τους υπόλοιπους συναδέλφους).

    Η αλήθεια είναι ότι προσπάθησα, πολύ βιαστικα, να δώσω τη γενική ιδέα και δεν ήθελα να επικεντρωθώ στο συγκεκριμένο. Ομως, τα γραφόμενά σου αποτελούν πηγή προς μελέτη και θέλω να σε ενημερώσω ότι αυτό θα πράξω.



    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2005, 11:20 6284 σε απάντηση της 6270

    Απ: ερώτηση σχετικά με το threading

    Μάνο διύλησες τον κώνωπα όντως !!!!
    Εύγε !!!
    Πέντε άστρα και από μένα !!!!


    Πάνος Αβραμίδης
  •  20-10-2005, 12:03 6286 σε απάντηση της 6233

    Απ: ερώτηση σχετικά με το threading

    Σας ευχαριστώ πολύ για τις απαντήσεις σας. Θα ξαναδοκιμάσω και θα σας ενημερώσω
  •  20-10-2005, 18:26 6294 σε απάντηση της 6286

    Απ: ερώτηση σχετικά με το threading

    Ρίξε μία ματιά και στο http://www.dotnetzone.gr/cs/forums/3400/ShowPost.aspx, στις δύο απαντήσεις μου.

    Αναφέρονται στο πως φορτώνουμε δεδομένα έχοντας δύο GUI threads, ένα της κύριας φόρμας και ένα μιάς splash. Ίσως να σου φανούν χρήσιμα.

    Άρης


    Aris
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems