2017-02-01 11 views

उत्तर

4

शायद निम्न समाधान आपके मामले में बेहतर फिट बैठता है, जो इस article पर आधारित है।

रद्दीकरण टोकन ट्रिगर होने पर यह सुनना बंद कर देगा, फिर आप ऑपरेशन को रद्द करने के लिए कस्टम तर्क लागू करने में सक्षम हैं। मेरे मामले में लूप को तोड़ने के लिए पर्याप्त है, लेकिन यह वास्तव में आप चाहते हैं कि कुछ भी हो सकता है।

public void Stop() 
    { 
     this.Status = ServerStatus.Stopping; 

     this.listener.Stop(); 
     this.cancellationTokenSource.Cancel(); 

     this.Status = ServerStatus.Stopped; 
    } 

    private async void ListenForConnections(CancellationToken cancellationToken) 
    { 
     try 
     { 
      while (this.Status == ServerStatus.Running) 
      { 
       var socketTask = this.listener.AcceptSocketAsync(); 

       var tcs = new TaskCompletionSource<bool>(); 
       using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) 
       { 
        if (socketTask != await Task.WhenAny(socketTask, tcs.Task).ConfigureAwait(false)) 
         break; 
       } 

       var context = new TcpContext(socketTask.Result); 

       this.OnConnectionReceived(context); 
      } 
     } 
     catch (ObjectDisposedException) 
     { 
      // Closed 
     } 
    } 
1

सबसे अच्छा आप कर सकते हैं सुनना हिस्सा धागे में लपेटें और जब आप थ्रेड पर निष्पादित करना रद्द करना चाहते हैं।

ऑब्जेक्ट डिस्प्ले अपवाद को पकड़ने के लिए सुनिश्चित करें जो विधि में हो सकता है। निचले स्तर TcpListener के लिए एक ही बात थी।

public void Stop() 
    { 
     this.Status = ServerStatus.Stopping; 
     this.listener.Stop(); 

     this.listeningThread.Abort(); 

     this.Status = ServerStatus.Stopped; 
    } 

    /// <summary> 
    ///  Listens for connections. 
    /// </summary> 
    private async void ListenForConnections() 
    { 
     try 
     { 
      while (this.Status == ServerStatus.Running) 
      { 
       var socket = await this.listener.AcceptSocketAsync(); 
       var context = new TcpContext(socket); 

       this.OnConnectionReceived(context); 
      } 
     } 
     catch (ObjectDisposedException) 
     { 
      // Closed 
     } 
    } 
+0

आपके द्वारा ऑफ़र किया गया डिज़ाइन वेब सॉकेट पर लागू नहीं है, मुझे लगता है :(आपके मामले में, आप एक स्वीकार्य थ्रेड बना सकते हैं। लेकिन वेब सॉकेट HTTP कनेक्शन (टीसीपी सॉकेट पर) पर एक अमूर्त है: उस समय तक मेरे पास एक HttpListenerContext है जिसे टीसीपी कनेक्शन पहले ही बनाया गया है और "AcceptWebSocketAsync" वास्तव में HTTP पर हैंडशेक करता है, इसलिए इसे थ्रेड पर ऑफलोड नहीं किया जा सकता है (प्रति क्लाइंट एक थ्रेड स्केलेबल नहीं है) –

2

हममम, आप HttpListener जो अनुरोध करने के लिए सुन रहा है से संदर्भ प्राप्त (संदर्भ में ही बात नहीं है, यह केवल आप के लिए अनुरोध/प्रतिक्रियाओं लपेटता जहाँ तक मैं समझता हूँ)। मुझे लगता है कि आपको HttpListener.Stop() पर कॉल करना चाहिए, क्या यह चाल चल जाएगा?

+0

उत्तर की तरह दिखता है। मुझे चाहिए इसे देखने के लिए कुछ समय। –

+0

@DenisGladkiy निश्चित बात, यदि संभव हो तो कृपया इस मामले पर टिप्पणी करें जब आप इसे चेक करते हैं। मैंने पूरी तरह से प्रलेखन पर मेरी धारणा आधारित है, 'एचटीपी लिस्टनर' और सामान्य ज्ञान के साथ मेरा अनुभव^-^यह अच्छा होगा पता है कि यह सही तरीका है (मैंने वेब सॉकेट के साथ काम नहीं किया)। –

+0

वेब सॉकेट के अनुसार आरएफसी केवल एक चीज है जिसे AcceptSocketAsync shou एलडी डू कई HTTP शीर्षलेख भेजना है: "ठीक है, अब से वेबस्केट के माध्यम से बात करते हैं"। मैंने HttpListener के स्रोत खोले हैं और AcceptSocketAsync बिल्कुल यह कर रहा है। खराब एपीआई डिज़ाइन की तरह दिखता है: आंतरिक रूप से केवल एक एसिंक कॉल होता है और इसमें रद्दीकरण टोकन के साथ अधिभार होता है :( –

संबंधित मुद्दे