2016-09-05 7 views
0

私はボタン1とフォームと、このコードサーバtcpを起動すると、フォームが消えるのはなぜですか?

private void button1_Click(object sender, EventArgs e) 
{ 
    ServerTCP s = new ServerTCP(); 
} 

そしてクラスserverTCP

public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    while (true) 
    { 
     TcpClient client = listen.AcceptTcpClient(); 
     Console.WriteLine("Client connected"); 
     NetworkStream stream = client.GetStream(); 
     byte[] buffer = new byte[client.ReceiveBufferSize]; 
     int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
     string message = Encoding.Unicode.GetString(buffer, 0, data); 
     int idgiorno = Int32.Parse(message); 
     Console.WriteLine("idgiorno: " + idgiorno); 
     client.Close(); 
    } 
} 

を持っている問題は、私はボタン1をクリックした後、フォームが消えるということです。スタートバーからまだ実行中であることがわかりますが、アイコンをクリックしても表示されません。フォームがフォーカスを失うようなものです。

+0

あなたのプログラムのメインスレッドで連続ループを実行しているため、クラッシュしてしまい、そのプログラムを使用できなくなったようです。 – ThePerplexedOne

+0

プログラムは、クライアントからの入力を待機し続けるサーバーです。アプリケーションを閉じる別のボタンがあるはずですので、フォームに焦点を当てる必要があります – Alessandro

+0

次に、メインのスレッドとは別のスレッドでコードを実行します。スレッドの詳細については、[こちら](https://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx)を参照してください。 – ThePerplexedOne

答えて

0

ここで何をしようとしているのか分かりますが、このビットを修正しても困ってしまうでしょう。

まず最初に、前に述べたように、フォームを失う理由は、あなたがメインスレッドに無限ループに入ったからです。これを避けるには、

using System.Threading.Tasks 
public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    Task myTask = new Task(() => 
    { 
     while (true) 
     { 
      TcpClient client = listen.AcceptTcpClient(); 
      Console.WriteLine("Client connected"); 
      NetworkStream stream = client.GetStream(); 
      byte[] buffer = new byte[client.ReceiveBufferSize]; 
      int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
      string message = Encoding.Unicode.GetString(buffer, 0, data); 
      int idgiorno = Int32.Parse(message); 
      Console.WriteLine("idgiorno: " + idgiorno); 
      client.Close(); 
     } 
    }); 
    myTask.Start(); 
} 

これは、管理タスクを自分で作成することなく、タスクをプールからスペアスレッドにディスパッチするための怠惰な方法です。この委譲はラムダ式と呼ばれます。

https://msdn.microsoft.com/en-GB/library/bb397687.aspx

これに伴う問題は、このスレッドがとにかくコンソールリソースへのアクセスを持っていないということですので、私はあなたがあなたのメッセージは表示されません怖いです。

あなたのコードでは、手続き的にすべてを書いています。これは、各ステップに必要な準備が整っていると仮定して、指示のリストを書いたことを意味します。例えば;

byte[] buffer = new byte[client.ReceiveBufferSize]; 

ここでまだデータを受信して​​いない場合は、ゼロを0にしてバッファを初期化しようとし、世界は終了します。

このすべてのステップを一歩一歩踏み出そうとするよりも、この2つのYouTube動画を優れた紹介としてご覧ください。彼らは完璧ではありませんが、あなたをさらに前進させるのに役立ちます。

https://www.youtube.com/watch?v=uXFso7xSSWk

https://www.youtube.com/watch?v=NanjpGKC2js

本当に、あなたのアプリケーションにアプローチする唯一の確実な方法は、「イベント駆動型プログラミング」を通じてですが、それは別の日のために何かあるかもしれません。

Good Luck!

0

まあ、基本的に次の呼び出しが返されたことがない:

ServerTCP s = new ServerTCP(); 

ServerTcpのコンストラクタは、無限ループが含まれている、そうではないだけ呼び出しは戻らないん、それもブロックUIスレッドを。ブロックされたUIスレッドでは、WM_ACTIVATEやWM_PAINTのようなウィンドウメッセージは決して処理されないため、フォームは使用できなくなります。

実際にはTcpListenerを非同期で使用する方法を検討する必要があります。 This is a good starting pointBeginAcceptTcpClientへの呼び出しを繰り返し実行すると、サーバーが実行され続けるため、ループも削除されます。

関連する問題