2016-10-03 8 views
1

私は、複数のクライアントを持つことができる非同期サーバーを作成しています。チャットクライアント/サーバアーキテクチャと同様に、すべてのクライアントは、クライアントの要求に基づいて各サーバの状態が変更されたときに更新されます。私は、多くの例があり、テストのための簡単なアプリケーションを書いています。私はちょうど今クライアント要求の処理を書いてきましたが、通常は遭遇しない状況に遭遇しました。ここで私が書いたサンプルサーバーだ:タスクは常に待つべきですか?

class Server 
{ 
    int _port; 
    TcpListener _listener; 
    IList<TcpClient> _clients = new List<TcpClient>(); 

    public Server(int port) 
    { 
     _port = port; 
     _listener = new TcpListener(IPAddress.Any, _port); 
    } 

    public async Task StartListening() 
    { 
     _listener.Start(); 
     Console.WriteLine("The server is listening on port {0}...", _port); 

     while (true) 
     { 
      try 
      { 
       var client = await _listener.AcceptTcpClientAsync(); 
       Console.WriteLine("We have a client!"); 
       _clients.Add(client); 
       Process(client); 

      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 
    } 

    private async Task Process(TcpClient client) 
    { 
     try 
     { 
      var stream = client.GetStream(); 
      var reader = new StreamReader(stream); 
      var writer = new StreamWriter(stream) { AutoFlush = true }; 
      char[] buffer = new char[1024]; 
      while (true) 
      { 
       var request = await reader.ReadLineAsync(); 
       if (request != null) 
       { 
        Console.WriteLine(request); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
      client.Close(); 
     } 
    } 

} 

ここでのProgram.csです:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var server = new Server(6029); 
     server.StartListening().Wait(); 
    } 
} 

タスクが待たれていないので、私はプロセスの呼び出しに警告が表示されます。私は呼び出し待ちのないコードの動作を理解していますが、これは私が必要とする動作を与えても、これを別に(ThreadPoolなど)コーディングしなければならないかと思います。タスクはいつも待たれるべきですか?

+1

'タスクが常に待たれるべき' NO ...火&忘れて作業はまた、いくつかの用途があります..? –

答えて

0

ここで本当に尋ねていることは分かりません。 で暗示されている具体的な質問と、これを別にコーディングする必要があるかどうか疑問に思っています。と、主に意見に基づく幅広い質問「タスクは常に待つべきですか?

後者では、正しいと思われる唯一の答えは「いいえ」です。 常にを実行する必要があります。

あなたが投稿したコードには間違いがあるようです。 1つは、おそらく完了できないasync Taskメソッドがあります。そのポイントは何ですか?あなたはそれをasync voidと宣言することもできます。このプログラムは、無限に長い時間スリープしたり、Console.ReadLine()メソッドなどでブロックするなど、他のメカニズムを介して無期限に待つことができます。

さらに、プログラムを正常に終了する方法を教えてください。サーバーがリスニングを停止したいときは、リスニングソケットを閉じます。 Process()によって返されたすべてのTaskオブジェクトを保存し、プロセスが完了する前に待機して、強制的にサーバーを強制的にリセットするのではなくサーバーを正常に終了させるようにします。

あなたが投稿したコードは、それ自体がアドバイスの方法に特有のものを提供するのに十分ではありません。初心者のコードのように見えますが、実際に何かをするよりもむしろいくつかの基本的な概念を示すために使用されます。したがって、必ずしもすべての状況で正しく動作するはずのコードとは異なるルールの対象となります。


あなたのコードの例を考えると、私はは、いくつかの点で、作成したタスクを待つだろうと私には思えます。 await Process(...)を必ずしも使用する必要はありません(実際には、一度に複数のクライアントを扱うことができないため、実際はそうしたくないかもしれませんが)。

しかし、Taskは、が常にである必要がありますか?いいえ、あなたの例では、あなたは説得力のない理由を示していません。ほとんどの場合、あなたはすべきです。それ以外の場合は、発生する可能性のある例外をすべて観察する機会が与えられます(これについては、Exception&hellip;予期しない例外をキャッチして、どのように処理するかを知っている必要があります)。しかし、まれなケースでは、開始したタスクは、単純な実用性(またはむしろタスクを観察しようとすることの非現実性)以外の理由がない限り、開始したタスクには何の注意も払わないと意味があります。


追加読書:
How to safely call an async method in C# without await
warning this call is not awaited, execution of the current method continues
Where to stop using async /await keywords?

関連する問題