2017-10-17 60 views
2

this answerDocs可以看出,對於併發流訪問,如果有一個唯一線程可供讀取,並且有一個唯一線程可供寫入,則可以在沒有問題的情況下執行讀取和寫入。在同一臺機器上併發訪問網絡流

我具有以下設置,如下圖還示出:

我有2個單獨的服務和Tester ServiceMy Service。他們每個人都有一個Server和一個Client。每個服務器和客戶端有2個任務WriterTaskReaderTask

我面臨的問題是,經過一定的時間後,客戶端會給出IOException 10060。事實上,另一方面的服務器運行良好。

現在,該文檔說明了一個用於讀/寫操作的獨特線程,如果它位於同一臺計算機上,是否存在問題?

其他人面臨過類似的情況嗎?

enter image description here

服務器的讀者:

private void ReaderTask(NetworkStream stream) 
    { 
     while (true) 
     { 
      // Some code 
      try 
      { 
       if (stream.CanRead) 
       { 
        var readTask = Task.Run(() => 
        { 
         MyObj message = null; 
         try 
         { 
          message = Deserialize<MyObj>(stream); 
          Console.WriteLine("ReaderTask: Read"); 
          // Some code 
         } 
         catch (IOException e) 
         { 
          Console.WriteLine("ReaderTask: " + e.Message); 
         } 
         return message; 
        }); 
        while(!readTask.Wait(1000)) 
        { 
         Console.WriteLine("ReaderTask: Wait 1000"); 
        } 
        if (readTask.Result != null) 
        { 
         Console.WriteLine("ReaderTask: Message received" + readTask.Result.toString()); 
        } 
       } 
      } 
      catch (IOException e) 
      { 
       Console.WriteLine("ReaderTask: " + e.Message); 
      } 
     } 
    } 

客戶編劇:

private void WriterTask(NetworkStream stream) 
    { 
     while (true) 
     { 
      // Some code 
      try 
      { 
       if (stream.CanWrite) 
       { 
        // message = getMessage(); 
        Serialize(stream, message); 
        Console.WriteLine("WriterTask: Write"); 
        // Some code 
       } 
      } 
      catch (IOException e) 
      { 
       Console.WriteLine("WriterTask: " + e.Message); 
      } 
      Thread.Sleep(1000); 
     } 
    } 
+0

是的,我面臨類似的情況,問題出現在我的代碼中,與讀寫線程之間的分隔無關。你怎麼知道「服務器運行良好」?在崩潰的客戶端的'NetworkStream.Read()'操作中是否存在當前阻塞的線程? –

+0

@ C.Evenhuis「服務器運行良好」 - 服務器的讀寫器任務生成日誌。所以我知道他們很好。但是服務器的閱讀器任務正在讀取流中的異步任務,並且無限期地被阻塞。我在下面的答案中提供了詳細的信息。如果你有更多的信息,如果你發佈一個答案並填寫更多的細節,這將是很好的。 –

回答

1

我想通了什麼問題了。

我沒有從我的服務器收到任何數據,因爲我沒有在客戶端上設置接收超時,例如client.ReceiveTimeout = 2000。因此,服務器會在讀取呼叫時阻止ReaderTask

我不是100%確定爲什麼當客戶端的WriterTask將寫入流時,服務器的ReaderTask將不會讀取任何內容並保持阻塞狀態。但是,一旦我在服務器上的客戶端對象超時,一切都開始正常運行。

那麼,如果具有獨特的ReaderTaskWriterTask的應用程序在同一臺計算機上,那麼是否存在問題?當你使用接收超時時,根本沒有問題。沒有收到超時,它不能正常工作(至少在我的情況下)。

+0

如果客戶端發送數據,服務器的「Read()」操作將不再阻塞 - 從描述中可以看出客戶端並未發送任何內容,因爲它正在等待數據。但是沒有任何代碼很難說。你不應該設置'ReceiveTimeout'來解決這個問題。 –

+0

@ C.Evenhuis在沒有接收超時的情況下,經過一些讀取和寫入操作後,所有突然的服務器讀取器將無限循環到while(!readTask.Wait(1000))中,同時任務在'message = Deserialize (流);'。即使客戶端的作者已經寫入了流 - 我從日誌中驗證了這一點。但是,現在,我不知道爲什麼會出現這種情況。查看我的問題以獲取相關代碼。 –

相關問題