Обработчик C# не создает и не работает при использовании .CreateHandler()

Я создаю игру, в которой я использую TCP/IP соединение. Проблема в том, что я использую .Вызовите, чтобы помочь мне получить и отправить сообщение.

Программа работает следующим образом: i’M my first window, i’m starting and connecting to the server like this :

{
        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;

    }

Я должен подождать, пока сервер отправит сообщение клиенту, а затем запустить клиент ( у меня есть функция.startGame(), которая использует .ShowDialog()и создает некоторые pictureBoxs)

Но нигде я не могу создать свою ручку. Я пытался положить this.createHandle()(читайте об этом здесь) ВGameWindow_Load, но до сих пор не работает. Если я пытаюсь отправить сообщение с:
workerSendData.RunWorkerAsync();Я получаю:

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

Что я могу сделать, чтобы получить мое handlerсоздано? Использование Thread.Sleepбудет спать весь мой пользовательский интерфейс, который не работает («решение» найдено в интернете)


Мой код для отправки сообщения :

 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();
    }

Мой код для получения данных:

  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());
            }
        }
    }

1 ответ

  1. Кажется, что вы не можете вызвать действие до Windowполной инициализации и загрузки. Предполагая, что вы работаете в Windows Forms, есть решение, предоставленное @Greg D по этому вопросу, но это не должно быть самым безопасным способом.

    Я бы посоветовал вам попытаться найти способ запустить работника только после загрузки окна (например, с помощью Loadedсобытия), так что дескриптор определенно готов, и эта ситуация не возникает.