2017-08-27 67 views
-1

我是C#的新手,目前正在使用命名管道將消息發送給對方的簡單消息傳遞應用程序。所以我有兩個Windows Forms應用程序項目在同一個解決方案中。兩個表單都有一個NamedPipeClientStream對象和一個NamedPipeServerStream對象和一個開始聊天按鈕。點擊開始聊天按鈕時,將執行以下代碼:如何在單獨的線程上運行NamedPipeServerStream.WaitForConnection()?

 this.Text = "Server - Waiting for a connection...."; 
     clientPipe.Connect(); 
     serverPipe.WaitForConnection(); 


     if (serverPipe.IsConnected) 
     { 
      this.Text = "Server - You are connected!"; 
      toggleButtons(); 
      txtBoxMsg.Focus(); 
      this.startBackgroundWorker(receiveWorker); 
     } 

當我只點擊窗體形式凍結的一個按鈕,我甚至無法退出。在做了一些研究之後,我意識到如果WaitForConnection()方法不是在單獨的線程上運行的話,它將被阻塞。任何人都可以解釋或展示一個例子來解決這個問題嗎?我在這裏查看了多個問題,我發現所有問題都需要在單獨的線程上運行,但實際上從來沒有給出過例子。

我也嘗試了下面的代碼,它可以防止窗體在單擊開始聊天按鈕時被凍結,但之後沒有更多的代碼被執行,這意味着在這種嘗試中管道實際上並沒有互相連接。

 Task.Run(() => 
     { 
      if (!serverPipe.IsConnected) 
      { 
       serverPipe.WaitForConnection(); 
      } 
     }).ContinueWith(_ => 
     { 
      if (serverPipe.IsConnected) 
      { 
       this.Text = "Client - You are connected!"; 
       // FileHandler.FileWriter("[CONVERSATION START: " + DateTime.Now + "]"); 
       toggleButtons(); 
       txtBoxMsg.Focus(); 
       this.startBackgroundWorker(receiveWorker); 
      } 
     }); 
+2

您應該避免任務延續('ContinueWith')並使用'await'來代替。後者使代碼更容易閱讀 – MickyD

回答

0

如何在一個單獨的線程上運行NamedPipeServerStream.WaitForConnection()?

因爲您的應用程序正在使用I/O,所以您通常希望避免線程,因爲線程在完成I/O操作時阻塞的大部分時間。線程最好留給計算操作。相反使用Taskawait他們。

有鑑於此,請使用NamedPipeServerStream.WaitForConnectionAsync()

例如

private async void button1_Click(object sender, System.EventArgs e) // <---- note async 
{     
    await clientPipe.ConnectAsync(); // good idea to make this async too 
    await serverPipe.WaitForConnectionAsync(); // async 

    if (serverPipe.IsConnected) 
    { 
     this.Text = "Server - You are connected!"; 
     toggleButtons(); 
     txtBoxMsg.Focus(); 
     . 
     . // don't spawn thread here, rather use async pipe method calls 
     . // e.g. 

     var buffer = new byte[2048];    
     var bytesRead = await serverPipe.ReadAsync (buffer, 0, buffer.Length); 
    } 
} 

注:上面的代碼需要.NET 4.6.2要在您的項目設置。

+0

其他事情,不適用於該方法的返回類型...我得到一個錯誤,說'不能等待空' –

+0

我試了兩個管道,都沒有工作。 該方法以我在問題中提出的方式工作。當我點擊這兩種形式的開始聊天按鈕時,我可以開始「聊天」,但是當我只點擊其中一個表單上的開始聊天按鈕時,表單正在等待連接,因此它凍結,我甚至無法退出形式而無需返回到Visual Studio並停止在那裏。 我想改變的是防止窗體凍結,當單擊開始聊天按鈕。 –

+0

對不起...我嘗試使用'await clientPipe.ConnectAsync()'以及'await serverPipe.WaitForConnectionAsync()',並且兩者都不工作,我仍然得到同樣的錯誤,說'不能等待空'。 –

相關問題