<?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>.NET Framework</title><link>https://www.dotnetzone.gr:443/cs/forums/14/ShowForum.aspx</link><description>Θέματα για threading, remoting, reflection, exception handling, security, regex κλπ.</description><dc:language>el</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Απ: Ασύγχρονα Sockets</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/67638.aspx</link><pubDate>Thu, 06 Oct 2011 02:25:38 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:67638</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/67638.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=67638</wfw:commentRss><description>&lt;p&gt;Τα lambdas δεν έχουν να κάνουν με το ότι δεν έπαιξε σωστά ο κώδικας. Αν δεν είχες βάλει το WaitOne και ο κώδικας με τα callbacks θα έσκαγε με τον ίδιο τρόπο. Και οι δύο μορφές του κώδικα είναι ουσιαστικά οι ίδιες.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Όσον αφορά το progress reporting, δεν χρησιμοποιείς πουθενά το ProgressChanged event οπότε τί εννοείς reporting? &lt;/p&gt;&lt;p&gt;Το cancellation γίνεται μέσω του CancellationSource και του CancellationToken που μπορείς να περάσεις σαν παράμετρο σε όλα τα tasks. Καλώντας έτσι την CancellationSource.Cancel() θα ακυρωθούν όλα τα tasks τα οποία ακούνε στο ίδιο token. Αυτό σημαίνει ότι μπορείς να συνδέσεις parent και child tasks έτσι ώστε να ακυρωθούν όλα όσο γίνεται πιο γρήγορα όταν κληθεί η Cancel, χωρίς να χρειαστεί να κάνεις εσύ κάποιο έλεγχο. Αντίθετα με τον BackgroundWorker θα πρέπει να ελέγχεις πρίν από κάθε iteration και κάθε BeginXXX ότι δεν έχει σηκωθεί το CancellationPending.&lt;/p&gt;&lt;p&gt;Ο κώδικας για τη χρήση του CancellationSource είναι πολύ απλός:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:black;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;var source &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CancellationTokenSource(); 
Task.Factory.StartNew(() =&amp;gt; 
    { 

......
    },source.Token);

.....&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="color:black;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;source.Cancel()&lt;/span&gt;&lt;/pre&gt;</description></item><item><title>Απ: Ασύγχρονα Sockets</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/67637.aspx</link><pubDate>Thu, 06 Oct 2011 02:10:53 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:67637</guid><dc:creator>George J. Capnias</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/67637.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=67637</wfw:commentRss><description>&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://www.dotnetzone.gr/cs/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;Παναγιώτης Καναβός:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Επιπλέον, η χρήση του BackgroundWorker δεν προσφέρει κανένα πλεονέκτημα σε σχέση με την χρήση ενός απλού TaskFactory.StartNew καθώς δεν χρησιμοποιείς ούτε καν το ProgressEvent. Ουσιαστικά σηκώνεις ένα και μοναδικό thread και όταν τελειώσει γράφεις κάτι στην κονσόλα. Ίσα-ίσα πρέπει να γράψεις παραπάνω διάσπαρτο κώδικα για να χειριστείς τα events που σηκώνει ο Background worker.&lt;/div&gt;&lt;p&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;/p&gt;&lt;p&gt;Εδώ θέλω να σταθούμε λίγο - ωραία η όλη ασύγχρονη προσέγγιση, αλλά χωρίς την αναφορά progress και την δυνατότητα canceling της διαδικασίας, δεν νομίζω ότι είναι εύκολο να έχεις κάτι "fire &amp;amp; forget" μέσα σε μια εφαρμογή. Η δική μου προσέγγιση της υλοποίησης "progress report &amp;amp; canceling" είναι ο BackgroundWorker, και όχι υλοποίηση του asynchronous. &lt;/p&gt;&lt;p&gt;Μην ξεχνάς ότι ο παραπάνω κώδικας με τα lamdas δεν μου έπαιξε&amp;nbsp;ποτέ σωστά, και ο άλλος κώδικας είναι work in progress ενός draft.&lt;/p&gt;&lt;p&gt;Πως θα πρότεινες να υλοποιηθεί το progress reporting και το canceling μιας ασύγχρονης ακολουθίας;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;George J.&lt;br&gt;&lt;/p&gt;</description></item><item><title>Απ: Ασύγχρονα Sockets</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/67603.aspx</link><pubDate>Sun, 02 Oct 2011 01:28:56 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:67603</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/67603.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=67603</wfw:commentRss><description>Το πρόβλημα δεν είναι στα lambdas αλλά στο ότι ξεκινάς συνέχεια ασύγχρονα operations μέσα σε ένα loop:&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!_worker.CancellationPending)
{
    _listener.BeginAcceptTcpClient(asyncAccept =&amp;gt;
    {
                        ...

    }, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;);
}&lt;/span&gt;&lt;/pre&gt;Έτσι ξεκινάς άπειρα BeginAcceptTcpClient μέχρι που σκάει η εφαρμογή.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Ο κώδικας που έχεις και δουλεύει δεν κάνει ασύγχρονο BeginAcceptTcpClient γιατί αμέσως μετά την Begin κάνεις Wait. Δεν έχει διαφορά ουσιαστικά σε σχέση με την κλήση της AcceptTcpClient μέσα σε loop. Θα μπορούσες να κάνεις ακριβώς το ίδιο και με lambdas:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (!_worker.CancellationPending)
{
   IAsyncResult a= _listener.BeginAcceptTcpClient(asyncAccept =&amp;gt;
    {
                        ...

    }, &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;null&lt;/span&gt;);
    a.AsyncWaitHandle.WaitOne();
}&lt;/span&gt;&lt;/pre&gt;Επιπλέον, η χρήση του BackgroundWorker δεν προσφέρει κανένα πλεονέκτημα σε σχέση με την χρήση ενός απλού TaskFactory.StartNew καθώς δεν χρησιμοποιείς ούτε καν το ProgressEvent. Ουσιαστικά σηκώνεις ένα και μοναδικό thread και όταν τελειώσει γράφεις κάτι στην κονσόλα. Ίσα-ίσα πρέπει να γράψεις παραπάνω διάσπαρτο κώδικα για να χειριστείς τα events που σηκώνει ο Background worker.&lt;/div&gt;</description></item><item><title>Απ: Ασύγχρονα Sockets</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/67531.aspx</link><pubDate>Tue, 27 Sep 2011 03:31:16 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:67531</guid><dc:creator>George J. Capnias</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/67531.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=67531</wfw:commentRss><description>&lt;p&gt;Εδώ ο ένοχος, που είχε την ανησυχία! Παραθέτω τον κώδικα που μου δουλεύει..&lt;/p&gt;&lt;pre&gt;&lt;span style="color:black;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationService
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;const&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; MessageSeparator &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"\r\n"&lt;/span&gt;;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;private&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; CommunicationService _instance;
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; CommunicationService Instance
        {
            get
            {
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (_instance == &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
                    _instance &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationService();

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;return&lt;/span&gt; _instance;
            }
        }

        BackgroundWorker _worker;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;private&lt;/span&gt; CommunicationService()
        {
            _worker &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; BackgroundWorker();
            _worker.DoWork += &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; DoWorkEventHandler(workerOnDoWork);
            _worker.RunWorkerCompleted += &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; RunWorkerCompletedEventHandler(workerOnRunWorkerCompleted);
            _worker.WorkerSupportsCancellation &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;true&lt;/span&gt;;
        }

        ~CommunicationService()
        {
            _worker.Dispose();
            _worker &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;;
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; RunWorker(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; port)
        {
            RunWorker(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationServiceStartEventArgs() { ServerEndPoint &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; IPEndPoint(0, port) });
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; RunWorker(CommunicationServiceStartEventArgs e)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (_worker.IsBusy)
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; InvalidOperationException();

            _worker.RunWorkerAsync(e);
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; CancelWorker()
        {
            _worker.CancelAsync();
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; AfterAcceptTcpClient(IAsyncResult resultAcceptTcpClient)
        {
            TcpListener _listener &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; resultAcceptTcpClient.AsyncState &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; TcpListener;
            TcpClient _client &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _listener.EndAcceptTcpClient(resultAcceptTcpClient);
            NetworkStream _stream &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _client.GetStream();

            TcpClientState _state &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; TcpClientState(_client);
            _stream.BeginRead(_state.IncomingBuffer, 0, _state.IncomingBuffer.Length, AfterRead, _state);
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; AfterRead(IAsyncResult resultRead)
        {
            TcpClientState _state &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; resultRead.AsyncState &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; TcpClientState;
            NetworkStream _stream &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _state.Client.GetStream();
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; bytesread &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _stream.EndRead(resultRead);

            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (bytesread &amp;gt; 0)
            {
                _state.IncomingData += Encoding.ASCII.GetString(_state.IncomingBuffer, 0, bytesread);

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt;[] sentences &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _state.IncomingData.Split(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt;[] { MessageSeparator }, StringSplitOptions.None);
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (sentences.Length &amp;gt; 1)
                {
                    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; position &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; 0; position &amp;lt; sentences.Length &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;-&lt;/span&gt; 1; position++)
                    {
                        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.OnMessageReceived(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationServiceReceiveEventArgs(sentences[position]) { ClientEndPoint &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _state.Client.Client.RemoteEndPoint &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; IPEndPoint });
                    }
                    _state.IncomingData &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; sentences[sentences.Length &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;-&lt;/span&gt; 1];
                }

                _stream.BeginRead(_state.IncomingBuffer, 0, _state.IncomingBuffer.Length, AfterRead, _state);
            }

        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; workerOnDoWork(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;object&lt;/span&gt; sender, DoWorkEventArgs e)
        {
            CommunicationServiceStartEventArgs args &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; e.Argument &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; CommunicationServiceStartEventArgs;
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (args !&lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
            {

                TcpListener _listener &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; TcpListener(args.ServerEndPoint);
                _listener.Start();
                Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"&amp;gt;&amp;gt;&amp;gt; Listener started..."&lt;/span&gt;);

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;while&lt;/span&gt; (!_worker.CancellationPending)
                {
                    IAsyncResult a &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _listener.BeginAcceptTcpClient(AfterAcceptTcpClient, _listener);
                    a.AsyncWaitHandle.WaitOne();
                }

                _listener.Stop();
                Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"&amp;gt;&amp;gt;&amp;gt; Listener stopped!"&lt;/span&gt;);
                _listener &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;;
            }
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; workerOnRunWorkerCompleted(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;object&lt;/span&gt; sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"&amp;gt;&amp;gt;&amp;gt; Listener finished!"&lt;/span&gt;);
        }


        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;event&lt;/span&gt; EventHandler&amp;lt;CommunicationServiceReceiveEventArgs&amp;gt; MessageReceived;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; OnMessageReceived(CommunicationServiceReceiveEventArgs e)
        {
            EventHandler&amp;lt;CommunicationServiceReceiveEventArgs&amp;gt; handler &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; MessageReceived;
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (handler !&lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
                handler(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;, e);
        }

    }

    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationServiceStartEventArgs : EventArgs
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; IPEndPoint ServerEndPoint { get; set; }
    }

    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationServiceReceiveEventArgs : EventArgs
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; MessageText { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; MessageBytes { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; IPEndPoint ClientEndPoint { get; set; }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; CommunicationServiceReceiveEventArgs()
        { }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; CommunicationServiceReceiveEventArgs(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; message)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.MessageText &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; message;
        }


    }

    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; TcpClientState
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;const&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; BufferSize &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; 512;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; TcpClient Client { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;byte&lt;/span&gt;[] IncomingBuffer { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; IncomingData { get; set; }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; TcpClientState(TcpClient Client)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.Client &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; Client;
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.IncomingBuffer &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;byte&lt;/span&gt;[BufferSize];
        }
    }&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Έχω ένα singleton, που χρησιμοποιεί ένα BackgroundWorker object για να μην είναι blocking, και στην συνέχεια, περιμένει να γίνει μια σύνδεση (blocking). Με το που γίνει η σύνδεση κάνει async accept, και διαδοχικά async reads μέχρι να κλείσει το port, ή να μην υπάρχουν άλλα δεδομένα να διαβάσει. Επειδή τα threads διαδέχονται το ένα το άλλο, για την φυσική συνέχεια μεταξύ τους, υπάρχει ένα state object που περιέχει το TCPClient που ελέγχει την σύνδεση, και το buffer που γεμίζει. Ο τρόπος που επικοινωνεί με τον "έξω κόσμο" είναι ένα event.&lt;/p&gt;&lt;p&gt;Ο κώδικας που ενεργοποιεί το server και παίρνει τα event:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:black;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; Program
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; SubscriptionServiceClient  subscriptionService;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt;[] args)
        {
            CommunicationService.Instance.MessageReceived += &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; EventHandler&amp;lt;CommunicationServiceReceiveEventArgs&amp;gt;(InstanceOnMessageReceived);
            CommunicationService.Instance.RunWorker(4070);

            &lt;span style="color:green;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;//Thread.Sleep(60000);&lt;/span&gt;
            Console.Read();

            CommunicationService.Instance.CancelWorker();
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; InstanceOnMessageReceived(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;object&lt;/span&gt; sender, CommunicationServiceReceiveEventArgs e)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;try&lt;/span&gt;
            {
                Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"{0}:{1} {2}"&lt;/span&gt;, e.ClientEndPoint.Address, e.ClientEndPoint.Port, e.MessageText);
                subscriptionService.SendMessage(e.MessageText);
            }
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;catch&lt;/span&gt; (Exception ex)
            {
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;throw&lt;/span&gt; ex;
            }
        }
    }&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Ξεκινάω το service και κάνω block το thread με ένα Console.Read()...&lt;/p&gt;&lt;p&gt;Η αλήθεια είναι ότι πριν καταλήξω σε αυτή την λύση είχα δοκιμάσει μια άλλη, που με απογοήτευσε... Έπαιζε για περίπου 60" και μετά κατέβαζε το μηχάνημα μιας και έτρωγε όλη την μνήμη μου - δεν κατάφερα να βρω τι έφταιγε, αν ενδιαφέρεσαι, να το δεις...&lt;/p&gt;&lt;pre&gt;&lt;span style="color:black;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationService
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;private&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; CommunicationService _instance;
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;static&lt;/span&gt; CommunicationService Instance
        {
            get
            {
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (_instance == &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
                    _instance &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationService();

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;return&lt;/span&gt; _instance;
            }
        }

        BackgroundWorker _worker;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;private&lt;/span&gt; CommunicationService()
        {
            _worker &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; BackgroundWorker();
            _worker.DoWork += &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; DoWorkEventHandler(workerOnDoWork);
            _worker.RunWorkerCompleted += &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; RunWorkerCompletedEventHandler(workerOnRunWorkerCompleted);
            _worker.WorkerSupportsCancellation &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;true&lt;/span&gt;;
        }

        ~CommunicationService()
        {
            _worker.Dispose();
            _worker &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;;
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; RunWorker(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; port)
        {
            RunWorker(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationServiceStartEventArgs() { ServerEndPoint &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; IPEndPoint(0, port) });
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; RunWorker(CommunicationServiceStartEventArgs e)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (_worker.IsBusy)
                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; InvalidOperationException();

            _worker.RunWorkerAsync(e);
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; CancelWorker()
        {
            _worker.CancelAsync();
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; workerOnDoWork(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;object&lt;/span&gt; sender, DoWorkEventArgs e)
        {
            CommunicationServiceStartEventArgs args &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; e.Argument &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; CommunicationServiceStartEventArgs;
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (args !&lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
            {
                List&amp;lt;TcpClient&amp;gt; clients &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; List&amp;lt;TcpClient&amp;gt;();

                TcpListener _listener &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; TcpListener(args.ServerEndPoint);
                _listener.Start();
                Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"&amp;gt;&amp;gt;&amp;gt; Listener started..."&lt;/span&gt;);

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;while&lt;/span&gt; (!_worker.CancellationPending)
                {
                    _listener.BeginAcceptTcpClient(asyncAccept =&amp;gt;
                    {
                        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;byte&lt;/span&gt;[] incomingBuffer &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;byte&lt;/span&gt;[512];
                        TcpClient _client &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _listener.EndAcceptTcpClient(asyncAccept);
                        clients.Add(_client);

                        NetworkStream _stream &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _client.GetStream();
                        IAsyncResult _readResult &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _stream.BeginRead(incomingBuffer, 0, incomingBuffer.Length, &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;);

                        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;while&lt;/span&gt; (!_worker.CancellationPending)
                        {
                            &lt;span style="color:green;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;// wait for the read operation to complete &lt;/span&gt;
                            _readResult.AsyncWaitHandle.WaitOne();
                         
                            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;int&lt;/span&gt; bytesRead &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _stream.EndRead(_readResult);

                            &lt;span style="color:green;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;// if zero bytes read, the connection is closed? &lt;/span&gt;
                            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (bytesRead == 0)
                            {
                                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;break&lt;/span&gt;;
                            }

                            &lt;span style="color:green;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;// raise event with data &lt;/span&gt;
                            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; message &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; Encoding.ASCII.GetString(incomingBuffer, 0, bytesRead);
                            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.OnMessageReceived(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;new&lt;/span&gt; CommunicationServiceReceiveEventArgs(message) { ClientEndPoint &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _client.Client.RemoteEndPoint &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;as&lt;/span&gt; IPEndPoint });

                            &lt;span style="color:green;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;// start the read operation again &lt;/span&gt;
                            _readResult &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; _stream.BeginRead(incomingBuffer, 0, incomingBuffer.Length, &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;);
                        }

                        _client.Close();
                        clients.Remove(_client);

                    }, &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;);
                }

                &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;foreach&lt;/span&gt; (TcpClient _client &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;in&lt;/span&gt; clients)
                {
                    _client.Close();
                }

                _listener.Stop();
                _listener &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;;
            }
        }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; workerOnRunWorkerCompleted(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;object&lt;/span&gt; sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine(&lt;span style="font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"&amp;gt;&amp;gt;&amp;gt; Listener finished!"&lt;/span&gt;);
        }


        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;event&lt;/span&gt; EventHandler&amp;lt;CommunicationServiceReceiveEventArgs&amp;gt; MessageReceived;

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;void&lt;/span&gt; OnMessageReceived(CommunicationServiceReceiveEventArgs e)
        {
            EventHandler&amp;lt;CommunicationServiceReceiveEventArgs&amp;gt; handler &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; MessageReceived;
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;if&lt;/span&gt; (handler !&lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;null&lt;/span&gt;)
                handler(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;, e);
        }

    }

    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationServiceStartEventArgs : EventArgs
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; IPEndPoint ServerEndPoint { get; set; }
    }

    &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;class&lt;/span&gt; CommunicationServiceReceiveEventArgs : EventArgs
    {
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; MessageText { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; MessageBytes { get; set; }
        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; IPEndPoint ClientEndPoint { get; set; }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; CommunicationServiceReceiveEventArgs()
        { }

        &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;public&lt;/span&gt; CommunicationServiceReceiveEventArgs(&lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;string&lt;/span&gt; message)
        {
            &lt;span style="color:blue;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;this&lt;/span&gt;.MessageText &lt;span style="color:red;font-family:Courier New;font-size:11px;font-weight:normal;background-color:transparent;"&gt;=&lt;/span&gt; message;
        }


    }&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Πάνω κάτω το ίδιο μοντέλο - υπάρχει το BackgroundWorker αλλά αντί να υπάρχουν τα async callbacks, προσπαθεί να γίνει υλοποίηση με lamdas&amp;nbsp;μέσα στο&amp;nbsp;workerOnDoWork()&amp;nbsp;για να κάνουν το async. Αν μπορείς να εντοπίσεις που έχω κάνει το λάθος...&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;George J.&lt;br&gt;&lt;/p&gt;</description></item><item><title>Ασύγχρονα Sockets</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/67482.aspx</link><pubDate>Sat, 24 Sep 2011 01:16:07 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:67482</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/67482.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=67482</wfw:commentRss><description>Κάποιος ρώτησε πρόσφατα πως μπορεί να χρησιμοποιήσει το Task Parallel Library για να φτιάξει ένα ασύγχρονο socket server ο οποίος θα μπορεί να εξυπηρετεί πολλούς clients. Προφανώς θα πρέπει να χρησιμοποιηθούν οι ασύγχρονες μορφές των συναρτήσεων του TcpListener (BeginAccept αντί για Accept) κλπ. Το πρόβλημα είναι ότι ο κώδικας που δημιουργείται είναι λίγο μακαρόνι. Έκανα μία προσπάθεια που περιγράφω παρακάτω αλλά θα ήθελα σχόλια και βελτιώσεις.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Καταρχήν, ο παρακάτω κώδικας είναι η σύγχρονη μορφή του server. Ο TcpListener δέχεται συνδέσεις σε ένα loop και ό,τι παραλάβει το αποθηκεύει σε ένα αρχείο. Το αξιοσημείωτο είναι ότι αυτή η μορφή είναι πολύ γρήγορη έτσι και τρέχει στο δικό της thread, καθώς δεν υπάρχει καθόλου κόστος από context switching ή την δημιουργία tasks. Χρειάστηκε να στείλω αρκετά μεγάλα μηνύματα (αρκετά KB) πριν αρχίσω να βλέπω διαφορά ανάμεσα σε αυτή τη μορφή και τις ασύγχρονες. Σημειωτέον, χρησιμοποίησα μέχρι 64 client threads τη φορά. Αν ο αριθμός client είναι πολύ μεγάλος, κάποιοι από αυτούς θα αρχίσουν να βλέπουν timeouts.&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&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;class&lt;/span&gt; TcpServer 
{        
	&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;void&lt;/span&gt; Start(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; port)
	{
		var listener &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; TcpListener(IPAddress.Any, port);
		listener.Start();
		Console.WriteLine(&lt;span style="color:#666666;background-color:#e4e4e4;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"Server Started"&lt;/span&gt;);

		Accept(listener);
	}

	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Accept(TcpListener listener)
	{
		&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;)
		{
			var client &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; listener.AcceptTcpClient();  &lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//BLOCKING&lt;/span&gt;
			Process(client);
		}
	}
	

	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Process(TcpClient client)
	{
		&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (NetworkStream stream &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; client.GetStream())
		{
			var fileName &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Path.GetTempFileName();
			
			&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;using&lt;/span&gt; (var fileStream &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; File.Open(fileName,FileMode.Create))
			{
				stream.CopyTo(fileStream);	&lt;span style="color:Green;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;//BLOCKING                    &lt;/span&gt;
			}
			File.Delete(fileName);
		}
		client.Close();
	}
}&lt;/span&gt;&lt;/pre&gt;&amp;nbsp;O server ξεκινάει &lt;i&gt;φυσικά&lt;/i&gt; με ένα Task.Factory.StartNew(()=&amp;gt;myServer.Start(12345)).&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Μία πρώτη βελτίωση είναι η επεξεργασία να γίνει ασύγχρονα. Αυτό γίνεται απλά τρέχοντας την Process στο δικό της task.&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;void&lt;/span&gt; Accept(TcpListener listener)
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;)
    {
        var client &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; listener.AcceptTcpClient();
        Task.Factory.StartNew(() =&amp;gt; Process(client));
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Επόμενο βήμα είναι να γίνεται ασύγχρονα και η αποδοχή των συνδέσεων, και εδώ είναι το μανίκι. Με την TaskFactory.FromAsync() μπορώ να φτιάξω ένα task από τις BeginAcceptClient, EndAcceptClient. Μόλις τελειώσει αυτό το task όμως θα πρέπει να δημιουργήσω άλλο ένα παρόμοιο για να παραλάβει την επόμενη σύνδεση. Δεν μπορώ να βάλω την FromAsync στο loop γιατί θα δημιουργηθούν άπειρα task. Πρέπει αναγκαστικά να δημιουργήσω το νέο task αφού ολοκληρωθεί το προηγούμενο. Και φυσικά ένα task που έχει ολοκληρωθεί δεν ξαναξεκινάει, για να πεις ότι θα έβαζα ένα restart στο Continue.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Μία λύση είναι το recursion που πρότεινε ο Νίκος ο Παλλαδινός στη συζήτηση για το &lt;a href="http://www.dotnetzone.gr/cs/forums/thread/67309.aspx"&gt;Ασύγχρονο Retry&lt;/a&gt;. Η Accept ξαναγράφεται ως εξής:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; Task Accept(TcpListener listener)
{
    &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; Task.Factory
        .FromAsync&amp;lt;TcpClient&amp;gt;(listener.BeginAcceptTcpClient, listener.EndAcceptTcpClient, listener)
        .ContinueWith(tc =&amp;gt;{
            Accept((TcpListener)tc.AsyncState);
            Process(tc.Result);
        });
}&lt;/span&gt;&lt;/pre&gt;Μόλις έρθει μία σύνδεση, καλείται ξανά η Accept για να παραλάβει την επόμενη και το Process γίνεται και αυτό στο δικό του ξεχωριστό task.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Σειρά έχει να ξεφορτωθούμε και τα μπλοκαρίσματα κατά την αποθήκευση στα αρχεία. Και εδώ μπορούμε να δουλέψουμε ασύγχρονα όπως παραπάνω, χρησιμοποιώντας τις BeginRead/EndRead κλπ μαζί με την TaskFactory.FromAsync. Ή μπορούμε να κλέψουμε και να χρησιμοποιήσουμε τα stream extensions από τα &lt;a href="http://blogs.msdn.com/b/pfxteam/archive/2010/04/04/9990342.aspx"&gt;ParallelExtensionsExtras&lt;/a&gt;, τα οποία έχουν έτοιμες ασύγχρονες μορφές για τις Stream.CopyTo, Stream.Read κλπ.&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; Task Process(TcpClient client)
{
	NetworkStream stream &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; client.GetStream();
	var fileName &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Path.GetTempFileName();

	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; stream
		.CopyStreamToFileAsync(fileName)
	.ContinueWith(t =&amp;gt;{
		var e &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; t.Exception;                                                                
		stream.Close();
		File.Delete(fileName);
		&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (e !&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;null&lt;/span&gt;) &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; e;
	}, TaskContinuationOptions.ExecuteSynchronously) 
	.ContinueWith(t2=&amp;gt;
		client.Close());
}       &lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Όλος μαζί ο server γίνεται πλέον&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&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;class&lt;/span&gt; TcpServer 
{        
	&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;void&lt;/span&gt; Start(&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;int&lt;/span&gt; port)
	{
		var listener &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; TcpListener(IPAddress.Any, port);
		listener.Start();
		Console.WriteLine(&lt;span style="color:#666666;background-color:#e4e4e4;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;"Server Started"&lt;/span&gt;);

		Accept(listener);
	}

	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; Task Accept(TcpListener listener)
	{
		&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; Task.Factory
			.FromAsync&amp;lt;TcpClient&amp;gt;(listener.BeginAcceptTcpClient, listener.EndAcceptTcpClient, listener)
			.ContinueWith(tc =&amp;gt;{
				Accept((TcpListener)tc.AsyncState);
				&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; ProcessAsync(tc.Result);
			}).Unwrap();
	}
	

	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; Task Process(TcpClient client)
	{
		NetworkStream stream &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; client.GetStream();
		var fileName &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Path.GetTempFileName();

		&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; stream
			.CopyStreamToFileAsync(fileName)
		.ContinueWith(t =&amp;gt;{
			var e &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; t.Exception;                                                                
			stream.Close();
			File.Delete(fileName);
			&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;if&lt;/span&gt; (e !&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;null&lt;/span&gt;) &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;throw&lt;/span&gt; e;
		}, TaskContinuationOptions.ExecuteSynchronously) 
		.ContinueWith(t3=&amp;gt;
			client.Close());
	}       
}&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Τί γνώμη έχετε και πως θα μπορούσε να βελτιωθεί ο κώδικας? Πως θα μπορούσε να γίνει πιο καθαρός και πιο μαζεμένος?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;Σκέφτηκα καταρχήν να χρησιμοποιήσω Iterator όπως στο retry αλλά δεν θα βόλευε καθώς θέλω τα δύο βήματα της διαδικασίας (accept, process) να μπορούν να εκτελούνται ανεξάρτητα. Με τον iterator θα έπρεπε να τελειώσει πρώτα το Process για να ξεκινήσει το επόμενο accept. Το παρακάτω δηλαδή δεν παίζει όπως θέλουμε:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;span style="color:Black;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;private&lt;/span&gt; IEnumerable&amp;lt;Task&amp;gt; AsyncIterator(TcpListener listener)
{
	&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;while&lt;/span&gt; (&lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;true&lt;/span&gt;)
	{
		var acceptTask &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; Task.Factory
			.FromAsync&amp;lt;TcpClient&amp;gt;(listener.BeginAcceptTcpClient, listener.EndAcceptTcpClient, listener);
		yield &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; acceptTask;
		var client &lt;span style="color:Red;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;=&lt;/span&gt; acceptTask.Result;
		yield &lt;span style="color:Blue;background-color:Transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; Process(client);
	}
}&lt;/span&gt;&lt;/pre&gt;Καμμία καλύτερη ιδέα?&lt;/div&gt;</description></item></channel></rss>