<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://www.dotnetzone.gr:443/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ADO.NET</title><link>https://www.dotnetzone.gr:443/cs/forums/78/ShowForum.aspx</link><description>Θέματα σχετικά με την προσπέλαση δεδομένων μέσω του ADO.NET και του System.Data namespace</description><dc:language>el</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/17122.aspx</link><pubDate>Mon, 25 Sep 2006 02:18:36 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:17122</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/17122.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=17122</wfw:commentRss><description>Συγγνώμη για την καθυστέρηση, αλλά πλέον δεν βρίσκω χρόνο ούτε για φτάρνισμα μέσα στη βδομάδα! &lt;br /&gt;
&lt;br /&gt;
Λοιπόν, επιβεβαίωσα ότι την Cancel πρέπει να την καλέσεις από άλλο thread. Και αυτό μεν είναι απόλυτα λογικό όταν μιλάμε για σύγχρονη εκτέλεση (αφού έχει ήδη μπλοκάρει το thread) αλλά ακούγεται περίεργο για ασύγχρονη εκτέλεση. Αυτό όμως εξηγείται αν σκεφτεί κανείς ότι όταν εκτελεί κανείς ασύγχρονα ένα command, ΔΕΝ εκτελείται σε διαφορετικό thread, όπως γινόταν στο ΝΕΤ 1.1, αλλά στο αρχικό thread. Η ασύγχρονη συμπεριφορά επιτυγχάνεται στο επίπεδο δικτύου. Το ADO.NET στέλνει στοιχεία στον SQL Server και περιμένει να λάβει callbacks από το driver δικτύου όταν ολοκληρωθεί η επεξεργασία από τον SQL Server. Το αρχικό thread συνεχίζει να εκτελείται μέχρι να ολοκληρωθεί η κλήση προς τον SQL Server. Αν δωθεί εντολή Cancel από το αρχικό thread, αυτή θα πρέπει να σταλεί στον SQL Server αφού ολοκληρωθεί η κλήση που εκκρεμμεί&lt;br /&gt;
&lt;br /&gt;
Όταν τώρα καλούμε την εντολή cancel, το ADO.NET λέει στον SQL Server να ακυρώσει την εκτέλεση της εντολής που εκτελούσε. Αν η εντολή ήταν ένα insert ή update το οποίο επηρέασε μερικά μιλιούνια εγγραφές, η ακύρωση θα καθυστερήσει μέχρι να γίνουν rollback οι αλλαγές. Η Cancel περιμένει να γίνουν όλα τα rollback πριν επιστρέψει για να μπορούμε να εκτελέσουμε νέες εντολές αμέσως μετά. Αν η Cancel επέστρεφε πριν προλάβουν να εκτελεστούν τα rollback, οι επόμενες εντολές δεν θα μπορούσαν να αγγίξουν τους πίνακες που εμπλέκονταν στην προηγούμενη εντολή και θα μπλοκάραν και αυτές αναγκαστικά.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16996.aspx</link><pubDate>Thu, 21 Sep 2006 06:19:30 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16996</guid><dc:creator>anjelinio</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16996.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16996</wfw:commentRss><description>Τελικά δοκίμασες τη λύση που πρότεινε ο KelMan ?? Φαίνεται να είναι το πάγιο recommendation για όταν θες να κάνεις cancel αν και στο MSDN λέει οτι το Cancel() "&lt;i&gt; προσπαθεί να ακυρώσει το command αν μπορεί, χωρίς να πετάει exception αν δεν τα καταφέρει&lt;/i&gt; " ... πάντως και στο &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql2k/html/sql_adonetprimer.asp"&gt;ADO.NET Primer&lt;/a&gt; που είδα, παλι το ίδιο λέει ... κάλεσε την Cancel απο άλλο thread:&lt;br&gt;&lt;p&gt;9 Tip: Use the &lt;b&gt;SqlCommand.Cancel()&lt;/b&gt; method to cancel long running or rogue queries. Create another thread and call the &lt;b&gt;Cancel&lt;/b&gt;
method on the running command. This will cancel the locally running
command and notify the server to kill the command process, thus freeing
up resources.&lt;/p&gt;&lt;br&gt;Άντε, και πες πας κιόλας ε;&lt;br&gt;</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16978.aspx</link><pubDate>Wed, 20 Sep 2006 21:24:52 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16978</guid><dc:creator>Dimitris Papadimitriou</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16978.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16978</wfw:commentRss><description>&lt;P&gt;&lt;BLOCKQUOTE&gt;&lt;table width="85%"&gt;&lt;tr&gt;&lt;td class="txt4"&gt;&lt;img src="/cs/Themes/default/images/icon-quote.gif"&gt;&amp;nbsp;&lt;strong&gt;pkanavos wrote:&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="quoteTable"&gt;&lt;table width="100%"&gt;&lt;tr&gt;&lt;td valign="top" class="txt4"&gt;Loop! Φτού-φτου-φτου! Όταν υπάρχει το select και το join, δεν χρειάζεται το loop! Σοβαρά τώρα, η χρήση ενός πίνακα σαν flag δημιουργεί πολύ περισσότερα προβλήματα απ' όσα λύνει. Αμέσως- αμέσως τίθεται θέμα locking μεταξύ όσων διαβάζουν και όσων γράφουν στο row. Ένα λάθος να κάνει κάποιος, και θα κλειδώσει όλους όσους χρησιμοποιούν το flag. Ο κώδικας αναγκαστικά θα γίνει πολύ πιο περίπλοκος,&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/BLOCKQUOTE&gt;&lt;/P&gt;
&lt;P&gt;Καλά ντε! Μη βαράς! Δεν ξέρω τι κάνει η sp σου; Εγώ το είπα γιατί ο καλύτερος τρόπος να σταματήσεις ένα thread είναι να το ειδοποιήσεις να σταματήσει μόνο του. Σίγουρα ο κώδικας θα γινόταν λίγο πιο περίπλοκος, αλλά αν γραφόταν σωστά δεν θα υπήρχε περίπτωση να μπερδευτούν τα threads.&lt;/P&gt;</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16975.aspx</link><pubDate>Wed, 20 Sep 2006 21:13:53 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16975</guid><dc:creator>KelMan</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16975.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16975</wfw:commentRss><description>Δοκίμασες αυτό που σου πρότεινα; Παίζει;</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16974.aspx</link><pubDate>Wed, 20 Sep 2006 21:00:35 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16974</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16974.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16974</wfw:commentRss><description>Loop! Φτού-φτου-φτου! Όταν υπάρχει το select και το join, δεν χρειάζεται το loop! Σοβαρά τώρα, η χρήση ενός πίνακα σαν flag δημιουργεί πολύ περισσότερα προβλήματα απ' όσα λύνει. Αμέσως- αμέσως τίθεται θέμα locking μεταξύ όσων διαβάζουν και όσων γράφουν στο row. Ένα λάθος να κάνει κάποιος, και θα κλειδώσει όλους όσους χρησιμοποιούν το flag. Ο κώδικας αναγκαστικά θα γίνει πολύ πιο περίπλοκος,&lt;br /&gt;
&lt;br /&gt;
Όπως και να έχει, στη δική μου περίπτωση έχω βαρειά insert-select-update για να δημιουργήσω ένα πίνακα για reporting. Σκοπός είναι αυτό το stored procedure να τρέχει γρήγορα, αλλά να μπορεί να το ακυρώσει ο χρήστης αν χρειαστεί. Η απορία μου είναι γιατί μπλοκάρει το Cancel, και γιατί δεν συμπεριφέρεται το Thread.Abort όπως περίμενα.</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16947.aspx</link><pubDate>Wed, 20 Sep 2006 06:59:46 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16947</guid><dc:creator>Dimitris Papadimitriou</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16947.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16947</wfw:commentRss><description>Εγώ θα έκανα κάτι άλλο. Θα είχα μια συγκεκριμένη εγγραφή στη βάση (μία στήλη μιας γραμμής) η οποία όταν πάρει μια συγκεκριμένη τιμή, η ίδια η stored procedure θα σταματάει τον εαυτό της. Προφανώς για να κρατάει τόσο πολύ φαντάζομαι ότι έχεις κάποιο loop. Μπορείς να ελέγχεις την τιμή αυτή σε κάθε iteration ή μια φορά σε 10 iterations κλπ.&lt;br /&gt;
&lt;br /&gt;
Οπότε όταν θέλεις να διακόψεις την εκτέλεση θα θέτεις αυτή την τιμή. Έτσι η stored procedure θα σταματάει και πολύ πιο ομαλά και φυσιολογικά.&lt;br /&gt;
&lt;br /&gt;</description></item><item><title>Απ: Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16939.aspx</link><pubDate>Wed, 20 Sep 2006 03:10:10 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16939</guid><dc:creator>KelMan</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16939.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16939</wfw:commentRss><description>&lt;P&gt;Χμμμ... Δύο περιπτώσεις μπορώ να σκεφτώ... Η πρώτη είναι να στέλνεις το cancel αλλά επειδή το tread που ξεκίνησε το Execute είναι blocked, να το λαμβάνει αφού έχει τελειώσει η δουλειά. Δοκίμασες να το υλοποιήσεις όπως στο παράδειγμα του MSDN, στέλνοντας το cancel από άλλο thread?&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Sub&lt;/span&gt; Thread_Cancel()&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Command&lt;/span&gt;.Cancel()&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;End&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Sub&lt;/span&gt; DoTheJob()&lt;br /&gt;&lt;br /&gt;      ...&lt;br /&gt;      ... (start the async job here)&lt;br /&gt;      ...&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Dim&lt;/span&gt; rThread2 &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;As&lt;/span&gt; Thread &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;New&lt;/span&gt; Thread( _&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;New&lt;/span&gt; ThreadStart(&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;AddressOf&lt;/span&gt; Thread_Cancel))&lt;br /&gt;      rThread2.Start()&lt;br /&gt;      rThread2.&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Join&lt;/span&gt;()&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;End&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 11px;font-weight: normal;"&gt;Sub&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;H δεύτερη είναι να μην μπορεί πραγματικά να κάνει cancel. Σε κάποιο blog post είχα διαβάσει ότι η Cancel θα *προσπαθήσει* να κάνει cancel αλλά δεν είναι σίγουρο ότι θα τα καταφέρει. Εξαρτάται από το state του server (ότι κι αν σημαίνει αυτό &lt;img src="/cs/emoticons/emotion-2.gif" alt="Big Smile" /&gt;)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Δεν πεθαίνει το άτιμο το SqlCommand!</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/16938.aspx</link><pubDate>Wed, 20 Sep 2006 02:30:20 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:16938</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/16938.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=16938</wfw:commentRss><description>&lt;P&gt;Λοιπόν, συνάντησα το εξής κουφό. Προσπαθώ να εκτελέσω ασύγχρονα ένα πολύ βαρύ stored procedure (ώρες!) , καλώντας το με την BeginExecuteNonQuery(). Η βάση είναι&amp;nbsp;SQL Server 2000, το ADO.NET 2.0 και ο provider ο SqlClient.&amp;nbsp;Το stored procedure εκτελείται κανονικότατα και επιστρέφει τα αποτελέσματα που περιμένω. Θέλω όμως ο χρήστης να έχει και τη δυνατότητα να διακόπτει την εκτέλεση του. &lt;/P&gt;
&lt;P&gt;Αμ δε! Δοκίμασα να καλέσω την Cancel του SqlCommand, η οποία όμως μπλοκάρει μέχρι να τελειώσει το stored procedure! Αν δεν καλέσω την Cancel αλλά τερματίσω την εφαρμογή, το SqlCommand εξακολουθεί να εκτελείται στο Thread Pool! &lt;/P&gt;
&lt;P&gt;Δοκίμασα να φτιάξω ένα δικό μου thread και να εκτελέσω εκεί το SqlCommand. Όταν ο χρήστης ζητάει ακύρωση, καλώ την Thread.Abort και λογικά περιμένω να εμφανιστεί ένα ThreadAbortException. Πάλι τίποτα! Και αυτή τη φορά, το ThreadAbortException εμφανίζεται μόνο όταν τελειώσει το SqlCommand!&lt;/P&gt;
&lt;P&gt;Τώρα κάτι άρχισα να ψυλιάζομαι. Απ' όσο ξέρω, το abort δεν είναι άμεσο όταν χρησιμοποιεί κανείς Interop, είτε COM είτε με P/Invoke. Εγώ όμως χρησιμοποιώ SqlClient! &lt;/P&gt;
&lt;P&gt;Έχει κανείς καμμία ιδέα?&lt;/P&gt;</description></item></channel></rss>