2017-01-15 17 views
0

私はTCP/IP接続を使用するゲームを作成しています。問題は、私がメッセージを受信して​​送るのを助けるために.Invokeを使用していることです。.CreateHandler()を使用するとC#ハンドラが作成されず失敗する

プログラムはこのように書き:私は私の最初のウィンドウよ、私は開始し、このようなサーバに接続しています:

{ 
     TcpListener listener = new TcpListener(IPAddress.Any, this.port); 
     listener.Start(); 
     try { 
      this.client = listener.AcceptTcpClient(); 
      gameWindow = new GameWindow(this.client, true); 
      gameWindow.StartGame(); 
     } 
} 

は、私はこのようにそれに接続しています:

{ 
IPEndPoint ipEnd = new IPEndPoint(this.serverIP, this.port); 
     { 
      try { 
       client.Connect(ipEnd); 
       if (client.Connected) { 
        gameWindow = new GameWindow(this.client, false); 
        gameWindow.StartGame(); 
       } 
      } 
} 

(フォームで)gameWindowのコンストラクタは次のようになります。

public GameWindow(TcpClient thisClient, bool isServer) 
    { 
     InitializeComponent(); 
     this.client = thisClient; 
     this.reader = new StreamReader(thisClient.GetStream()); 
     this.writer = new StreamWriter(thisClient.GetStream()); 

     this.writer.AutoFlush = true; 

    } 

私はワイ必要がありますサーバがクライアントにメッセージを送信し、クライアントを起動するためのトン(私は.ShowDialog()を使用し、いくつかのpictureBox Sを作成する機能.startGame()を持っている)

しかし、どこにも、私は私のハンドルが作成されません得ることができます。私はGameWindow_Loadthis.createHandle()(ここでそれについて読む)を入れようとしましたが、まだ動作しません。私がメッセージを送信しようとした場合: workerSendData.RunWorkerAsync();私が取得:

Additional information: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

私は私のhandlerが作成されますし何ができますか?データを受信するための

private void workerSendData_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (client.Connected) { 
      this.writer.WriteLine(this.toSend); // aici trimitem datele. 
      // de modificat : aici vom adauga in lista noastra miscarile. 
      this.Invoke(new MethodInvoker(delegate() { MessageBox.Show("Me:" + this.toSend + "\n"); })); 
     } 
     else { 
      MessageBox.Show("Send failed"); 
     } 
     workerSendData.CancelAsync(); 
    } 

マイコード:

メッセージを送信するための Thread.Sleep動作しません私の全体のUI、(インターネット上で見つかった「ソリューション」)をスリープします


私のコードを使用して

private void workerReceiveData_DoWork(object sender, DoWorkEventArgs e) 
    { 
     while (client.Connected) { 
      try { 
       this.received = this.reader.ReadLine(); 
       this.myTurn = true; 
       this.Invoke(new MethodInvoker(delegate() { 
        MessageBox.Show("This has been received: " + this.received); 
        /*this.tbReceive.AppendText("You:" + this.received + "\n");*/ 
       })); 
       this.received = ""; 
      } 
      catch (Exception x) { 
       MessageBox.Show(x.Message.ToString()); 
      } 
     } 
    } 
+0

'Load'イベントの中でハンドルは既に作成されています。あなたのクラスを外部からインスタンス化した後に、 'CreateHandle'メソッドを使用してください。 – abto

答えて

0

Windowが完全に初期化されて読み込まれる前にアクションを呼び出すことはできないようです。 Windowsフォームで作業していると仮定すると、@ Greg Dで提供されるソリューションがthis questionにありますが、最も安全な方法ではありません。

ウィンドウがロードされた後で(たとえば、Loadedイベントを使用して)ワーカーを開始する方法を見つけようとすると、ハンドルが確実に準備でき、この状況は発生しません。

関連する問題