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

 

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

Ερώτηση

Îåêßíçóå áðü ôï ìÝëïò gsint. Τελευταία δημοσίευση από το μέλος gsint στις 28-04-2005, 11:53. Υπάρχουν 9 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  26-04-2005, 13:58 1714

    Ερώτηση

    Καινούργιος είμαι και εγώ και έχω 2 απλές (?) ερωτήσεις
    1. Εχω μια MDI φόρμα και σε ένα menu της κάνω
      

    Dim aDataGrid2 As DataGrid2 = New DataGrid2

    aDataGrid2.MdiParent = Me

    aDataGrid2.Show()
    όπου DataGrid2 είναι μια απλή φόρμα με ένα datagrid πάνω το οποίο έχει ένα demanding query και καθυστερεί. Πως μπορώ να χρησιμοποιήσω thread εδώ;;;
    Μπορεί κάποιος να δώσει ένα απλό παράδειγμα κώδικα;;;

    2. πως ένα DataReader μπορεί να εμφανιστεί σε ένα DataGrid όπως το DataTable; (πολύ απλά dtGrid.DataSource = DtTable)


    Ευχαριστώ εκ των προτέρων
    Γιώργος Συντέτας

  •  26-04-2005, 17:00 1717 σε απάντηση της 1714

    Re: Ερώτηση

    Καλώς ήλθες στο forum Smile

    1. Για να μπορέσεις να χρησιμοποιήσεις ένα καινούργιο thread.
    Κατ αρχήν πρέπει να προσθέσεις στην αρχή του κώδικα το

    Imports System.Threading

    Στην συνέχεια θα πρέπει να φτιάξεις ένα subroutine που να περιέχει το κώδικα που δημιουργεί και τρέχει την φόρμα που θες. Έστω...

    Private Sub TheLongRunningTask()
    'Αυτή η subroutine κάνει προσομοίωση σε ένα task που θέλει πολύ ώρα να
    'τρέξει. frmTaskProgress είναι η φόρμα που θέλουμε να τρέξουμε

    Dim f As New
    frmTaskProgress
    f.Show()
    f.Refresh()
    'Αναγκάζει την φόρμα να ζωγραφιστεί

    Dim i As
    Integer
    For i = 1 To
    10
    Thread.CurrentThread.Sleep(500)
    'Καθυστέρηση 0,5 δευτ.
    Next

    'Αφαίρεση της φόρμας από τη μνήμη
    f.Hide()
    f.Dispose()

    End Sub

    Τέλος φτιάχνουμε τον κώδικα για το καινούργιο thread και το τρέχουμε...

    Dim t As New Thread(AddressOf TheLongRunningTask) 'Δημιουργία νέου thread
    t.Start()
    'Έναρξη εκτέλεσης του thread

    Αυτός είναι ο τρόπος που φτιάχνεις το thread και το τρέχεις. Υπάρχουν πολλά μειονεκτήματα, όπως ότι το ξεκινάς και μετά πρέπει από μόνο του να καθαρίσει τα resources που χρησιμοποίησε, δεν επιστρέφει κάτι.

    2. Το DataReader μπορεί να εμφανιστεί όσο απλά αναφέρεις:


    Dim connString As String = "Server=localhost;Database=Northwind;Integrated Security=SSPI"
    Dim sql As String
    = "SELECT * FROM Products"
    Dim conn As SqlConnection = New
    SqlConnection(connString)
    Dim command As SqlCommand = New
    SqlCommand(sql, conn)

    Try
    conn.Open()
    Dim reader As
    SqlDataReader = command.ExecuteReader()
    Me
    .DataGrid1.DataSource = reader
    Me
    .DataGrid1.DataBind()

    Catch ex As
    Exception
    ' Εδώ πάει ο κώδικας για τον χειρισμό των λαθών
    Finally
    conn.Close()
    End Try

    Δεν νομίζω ότι θα συναντήσεις πρόβλημα...

    Για ότι άλλο, εδώ είμαστε! Wink

    George J.


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

    Re: Ερώτηση

    Γιώργο (gcapnias), μήπως ο Γιώργος (gsint) ( Smile ) μιλώντας για το thread εννοεί οτι το loading του datagrid και όχι όλη η φόρμα θα πρέπει να γινεται σε ξεχωριστό thread? Κατι τέτοιο κατάλαβα εγώ. Δηλ. η φόρμα να εμφανίζεται κανονικά, αλλά να υπάρχει ένα thread που να φέρνει τα data και όταν τελειώσει (προφανώς με κάποιο callback) να γίνεται bind με το datagrid της φόρμας που άνοιξε.

    Σιγουρα ο Γιώργος (gsint) θα μας λύσει την απορία, απλά επειδή έτσι το κατάλαβα εγώ είπα να το αναφέρω.

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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  26-04-2005, 23:05 1724 σε απάντηση της 1721

    Re: Ερώτηση

    Γειά σου Γιώργο, πιστεύω ότι σε αυτό το post (http://www.dotnetzone.gr/forums/ShowPost.aspx?PostID=1429) θα βρεις ό,τι χρειάζεσαι για το πως μπορείς να κάνεις αυτό που λες... Χρειάζεται μόνο λίγη προσαρμογή στη δική σου περίπτωση αλλά κατά τ'άλλα το concept είναι ίδιο.


    Vir prudens non contra ventum mingit
  •  26-04-2005, 23:46 1726 σε απάντηση της 1724

    Re: Ερώτηση

    Χεχε, αυτό ήταν δικό μου post Smile Φαντάσου δηλαδή σε τι κατάσταση βρίσκομαι που ούτε που θυμάμαι...Smile Οντως, ίσως μπορεί να βοηθήσει το Γιώργο αυτό το post υπό την έννοια οτι επιτρέπει σε μια φόρμα να ενημερώνεται από διαδικασίες που εκτελούνται σε κάποιο άλλο thread. Ετσι, μπορεί π.χ. η διαδικασία η οποία φορτώνει τα δεδομένα να εκτελείται σε ένα thread και μετά το πέρας της να ενημερώνεται το datagrid της φόρμας, όπως διευκρίνιζα σε προηγούμενο μήνυμα. (Αν αυτό είναι το ζητούμενο).




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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  27-04-2005, 14:06 1741 σε απάντηση της 1717

    Re: Ερώτηση

    Λυπάμε αλλά δεν παίζει τίποτα
    1. Η displayDataGrid2 δουλεύει από μόνη της, αρα;;; Με την "aDataGrid2.MdiParent = Me" μου σκάει run-time error πως σε ένα thread δεν μπορώ να έχω reference εκτός του thread. ok, αλλά και πάλι η φόρμα εμφανίζεται στην οθόνη και "χάνεται" από μόνη της... Τι μπορεί να συμβαίνει;;;

    Private Sub MenuItem7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem7.Click

    'displayDataGrid2()

    Dim objThread As Thread

    objThread = New Thread(AddressOf displayDataGrid2)

    objThread.Start()

    End Sub

    Private Sub displayDataGrid2()

    Dim aDataGrid2 As DataGrid2 = New DataGrid2

    'aDataGrid2.MdiParent = Me

    aDataGrid2.Show()

    aDataGrid2.Refresh()

    End Sub

    2.

    Dim connString As String = "Server=localhost;Database=Northwind;Integrated Security=SSPI"

    Dim sql As String = "SELECT * FROM Products"

    Dim conn As SqlConnection = New SqlConnection(connString)

    Dim command As SqlCommand = New SqlCommand(sql, conn)

    Try

    conn.Open()

    Dim reader As SqlDataReader = command.ExecuteReader()

    DtgSearch.DataSource = reader

    DtgSearch.DataBind()

    Catch ex As Exception

    ' Εδώ πάει ο κώδικας για τον χειρισμό των λαθών

    Finally

    conn.Close()

    End Try

    Δεν κάνει καν compile με μήνυμα
     'DataBind' is not a member of 'System.Windows.Forms.DataGrid'.
    Αρα;;;

    Τέλος πάντων, διάβασα στο help πως αυτές οι κλάσεις SqlConnection κλπ είναι μόνο για SQL Server. Αν αυτό είναι αλήθεια τότε δεν έχει νόημα να μου απαντηθεί το 2 καν, δεν μου αρέσουν τα "κλειστά" κόλπα...


    Ευχαριστώ
    ΓΣ

  •  27-04-2005, 15:16 1745 σε απάντηση της 1741

    Re: Ερώτηση

    Για το 2. ... τί εννοείς "κλειστά" κόλπα?  Η λογική του ADO.NET είναι ότι υπάρχουν κάποια στανταρ interfaces που υλοποιούνται από διαφορετικό provider για κάθε βάση. Αν βέβαια βιάζεσαι, ή δεν ενδιαφέρεσαι να τρέξεις την εφαρμογή σε διαφορετικές βάσεις μπορείς να παίξεις κατευθείαν με τους provider αντί για τα Interface.

    Όσο για το compile, ο compiler έχει δίκιο γιατί ο κώδικας που χρησιμοποιείς είναι για ASP.NET και όχι για Windows Forms. Το DataGrid των Windows.Forms δεν έχει μέθοδο DataBind, ούτε και την χρειάζεται. Η DataBind είναι μέθοδος του Web DataGrid και χρησιμοποιείται για να "διαβάσει" τα δεδομένα από το datasource του grid και μετά να δημιουργηθεί το HTML που θα σταλεί στον broswer. Εξάλλου, οι DataReaders δεν περιέχουν δεδομένα και δεν μπορούν να χρησιμοποιηθούν σαν DataSources.
      Ίσως να νομίζεις ότι χρησιμοποιώντας ένα datareader το grid θα φορτωθεί πιο γρήγορα. Για να εμφανιστεί όμως το grid πρέπει να έχει όλα τα δεδομένα του, οπότε ένα reader θα έπρεπε πάλι να φορτώσει όλα τα δεδομένα και μετά να τα περάσει στο grid.

    Η απλούστερη λύση είναι να βάλεις ένα connection, adapter και dataset στη φόρμα σου και να θέσεις σαν datasource του grid το dataset. Στο load χρησιμοποιείς μία απλή γραμμή:
       mySqlDataAdapter.Fill(myDataSet)
    και τελείωσες. Ούτε connection.Open, ούτε readers.

    Αν θες οπωσδήποτε να δημιουργήσεις το dataset με κώδικα θα πρέπει να γράψεις τα παρακάτω:


    Dim connString As String = "Server=localhost;Database=Northwind;Integrated Security=SSPI"

    Dim sql As String = "SELECT * FROM Products"

    Dim conn As SqlConnection = New SqlConnection(connString)

    Dim command As SqlCommand = New SqlCommand(sql, conn)

    Try

    Dim mySet As DataSet = New DataSet

    Dim myAdapter As SqlDataAdapter = New SqlDataAdapter(command)

    myAdapter.Fill(mySet)

    DtgSearch.DataSource = mySet

    Catch ex As Exception

    ' Εδώ πάει ο κώδικας για τον χειρισμό των λαθών

    Finally

    'Δεν χρειάζεται κλείσιμο

    End Try


     






    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  27-04-2005, 20:39 1753 σε απάντηση της 1745

    Re: Ερώτηση

    Πιθανώς με το "κλειστά κόλπα" εννοεί ότι υπάρχει μόνο υποστήριξη για Microsoft SQL Server. Το SQLConnection είναι για τον Microsoft SQL Server. Δεν είπε εδώ κανένας μας ότι, υπάρχουν και άλλοι providers, ODBC, OLEDB, Oracle, mySQL με αντίστοιχα ονόματα OracleConnection, κοκ...

    Καλά πόσο, αφηρημένος είμαι... Έκανα copy & paste το κώδικα από WebForm. Ούτε που σκέφτηκα το WinForm.

    Μήπως στην συγκεκριμένη περίπτωση θα ήταν καλύτερα να δηλώσουμε ένα Delegate και να ξεκινήσουμε το Thread με BeginInvoke και να του περνάμε ένα dataset και να το παίρνουμε πίσω; Υπόθεση κάνουμε...

    Από την άλλη για άλλη μια φορά φαίνεται ότι όταν αρχίζουμε και μιλάμε για treading αρχίζουμε και νιώθουμε - κάνω quote


     cap wrote:

    Μου φαίνεται οτι άγγιξα το twilight zone... Smile


    Δεν είπαμε ότι να το παίξεις με free threading και πολλαπλά threads είναι και το πιο εύκολο πράγμα, αλλά σίγουρα γίνεται πολύ πιο εύκολα στη VB.NET.

    George J.

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

    Re: Ερώτηση

    Ορίστε ένα ολοκληρωμένο παράδειγμα για ασύγχρονο fill του dataset (φτάνουν 4Μ εγγραφέςWink. Η διαφοροποίηση σε ότι είχαμε πει στο post που σου είχα προτείνει να διαβάσεις είναι ότι εδώ δεν υπάρχει η ανάγκη να κάνεις update τα controls της φόρμας κατά τη διάρκεια του long-running-operation ήτοι το fill του dataset, αλλά απλά να κάνεις bind το datagrid μόλις τελειώσει το fill. Πρόσεξε γιατί εδώ το

     

    DataGrid1.CaptionText = ...

     

    είναι παράνομο και πρέπει να γίνεται όπως έχουμε πει στο συγκεκριμένο post, απλά το χρησιμοποίησα για να μην επεκταθεί πολύ ο κώδικας.

     

    Το μόνο που χρειάζεται είναι να κάνεις copy/paste τον κώδικα σε μια φορμούλα με ένα datagrid και δύο buttons, να έχεις sql server και τη northwind...

     

     

    Dim fillerThread As Thread

    Dim fillerThreadStart As New ThreadStart(AddressOf QueryDataBase)

    Dim DataGridBinder As New MethodInvoker(AddressOf Me.BindDataGrid)

     

    Dim cnNorthwind As New SqlConnection("data source=localhost;initial catalog=northwind;integrated security=SSPI;")

    Dim daProducts As New SqlDataAdapter("SELECT Products.* FROM Orders CROSS JOIN Products CROSS JOIN Products Customers", cnNorthwind)

    Dim dsNorthwind As New DataSet

     

    Public Sub BindDataGrid()

        DataGrid1.DataSource = dsNorthwind

        DataGrid1.DataMember = "BigTable"

        daProducts = Nothing

        dsNorthwind = Nothing

    End Sub

     

    Public Sub QueryDataBase()

        Try

            cnNorthwind.Open()

            DataGrid1.CaptionText = "Running query..."

            daProducts.Fill(dsNorthwind, "BigTable")

            DataGrid1.CaptionText = "Query complete."

            Me.BeginInvoke(DataGridBinder)

        Catch thEx As ThreadAbortException

        Finally

            cnNorthwind.Close()

            cnNorthwind.Dispose()

            cnNorthwind = Nothing

            fillerThread = Nothing

        End Try

    End Sub

     

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

        fillerThread = New Thread(fillerThreadStart)

        fillerThread.IsBackground = True

        fillerThread.Name = "UpdateThread"

        fillerThread.Start()

    End Sub

     

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

        fillerThread.Abort()

        DataGrid1.CaptionText = "Query cancelled."

    End Sub

     

     

     

    Και καθώς έγραφα αυτό το post, τσουπ! Έρχεται το post του gcapnias…

     gcapnias wrote:

    Μήπως στην συγκεκριμένη περίπτωση θα ήταν καλύτερα να δηλώσουμε ένα Delegate και να ξεκινήσουμε το Thread με BeginInvoke και να του περνάμε ένα dataset και να το παίρνουμε πίσω; Υπόθεση κάνουμε...

    Όχι, δεν χρειάζεται να κάνει βόλτες το DataSet... Tο κόλπο είναι να χρησιμοποιήσεις δύο delegates, ένα το ThreadStart και ένα το MethodInvoker. Το πρώτο κάνει την δουλειά που θέλουμε και το δεύτερο ανανεώνει τη φόρμα γιατί όπως είπαμε "Το μυστικό είναι ότι το control χρησιμοποιεί το delegate για να καλέσει τη μέθοδο στο context του δικού του thread!"


    Vir prudens non contra ventum mingit
  •  28-04-2005, 11:53 1767 σε απάντηση της 1753

    Re: Ερώτηση

    Συγγνώμη αλλά δεν κατάλαβα, τι μου λέτε...

    Ας αφήσουμε το SqlDataReader στην άκρη και ας δούμε ξεχωριστά το θέμα του thread.

    1. Η displayDataGrid2 δουλεύει από μόνη της, αρα;;; Με την "aDataGrid2.MdiParent = Me" μου σκάει run-time error πως σε ένα thread δεν μπορώ να έχω reference εκτός του thread. ok, αλλά και πάλι η φόρμα εμφανίζεται στην οθόνη και "χάνεται" από μόνη της... Τι μπορεί να συμβαίνει;;;

    Private Sub MenuItem7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem7.Click

    'displayDataGrid2()

    Dim objThread As Thread

    objThread = New Thread(AddressOf displayDataGrid2)

    objThread.Start()

    End Sub

    Private Sub displayDataGrid2()

    Dim aDataGrid2 As DataGrid2 = New DataGrid2

    'aDataGrid2.MdiParent = Me

    aDataGrid2.Show()

    aDataGrid2.Refresh()

    End Sub


    Οπως είπα και παραπάνω έχω μια απλή φόρμα και θέλω να την ανοίξω μια mdi child (αυτό δεν είναι 100% απαραίτητο, είναι όμως επιθυμητό) σε άλλο thread. Γίνεται; Και αν ναι πως; Ο κώδικας που παραθέτω δείχνει την φόρμα, η οποία αμέσως εξαφανίζεται !!!

    Ευχαριστώ για τον χρόνο σας

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