Ошибка вывода консоли в форму - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день ещё раз. При написании программы возникла следующая проблема. При запуске выскакивает исключение с сообщением типа "Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'txtConsole' не из того потока, в котором он был создан." исходник:
public partial class FormGUI : Form
    {
        TextWriter _writer = null;

        public FormGUI()
        {
            InitializeComponent();
            var th = new System.Threading.Thread(Launcher);
            th.Start();
        }

        /* public void TotxtConsol1e(string text)
         {
             if (InvokeRequired)
                 BeginInvoke((Action<string>)TotxtConsole, text);
             else
                 Console.WriteLine(text);
         }*/
 
        private void Launcher()
        {
            this.BeginInvoke(new Action(console_print));
        }
 
        //многопотоковочка
        private void console_print()
        { 
            Console.WriteLine(Listener.response + Environment.NewLine) ; // добавляем строку и начинаем новую
        }
 
        private void FormGUI_Load(object sender, EventArgs e)
        {
            // Инстанциируем writer
            _writer = new TextBoxStreamWriter(txtConsole);
            // Перенаправляем выходной поток консоли
            Console.SetOut(_writer);
            Console.WriteLine("Выберите порт и нажмите 'пуск' ");
        }
 
        private void Launch_Click(object sender, EventArgs e)
        {
            Listener.port = Convert.ToInt32(comboBox1.Text);
            Listener.StartClient();
            Launcher();
        }
 
    } public class TextBoxStreamWriter : TextWriter
    {
        TextBox _output = null;
        public TextBoxStreamWriter(TextBox output)
        {
            _output = output;
        }
        public override void Write(char value)
        {
            base.Write(value);
            _output.AppendText(value.ToString());
        }
        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }
    }private static void Receive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;
 
            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
            response = state.sb.ToString();
            Console.WriteLine(response);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
Так же ругается, что переменная state не определена в текущем контексте, когда доходит до точки вылета в коде переноса в консоль. Вроде отдельный поток создал, разве только что не пытался закрыть его через join, но проблема вроде бы не в этом. Что следует сделать, чтобы не было этого исключения, так как в принципе сообщения в консоль выводятся и внутри функций таких как приведенный выше приём?
UPD - программа работает через раз при переносе строки TextWriter _writer = null; в место сразу после объявления класса. Потом обратно в FormGUI_Load. В чем причина этих вещей разобраться не могу, что-то напутал с потоками
UPD [2] - при выполнении программы пошагово почему-то не вылетает никогда. Что это за бред? Кто-нибудь сталкивался с подобным? Спасите чайника

Решение задачи: «Ошибка вывода консоли в форму»

textual
Листинг программы
// 
//
 
#include "stdafx.h"
//#include "winsock.h"
#include "winsock2.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <clocale>
 
 
WSADATA ws;
#define SERVER_PORT 5555
#define SERVER_MAX_CONN 32
 
struct sockaddr_in SERVER_ADDR;
struct sockaddr_in CLIENT_ADDR;
char *buff[32];
int error;
 
char sHELLO[64];
char *psHELLO;
 
int _tmain(int argc, _TCHAR* argv[])
{
    
    SetConsoleCP(1251);// установка кодовой страницы win-cp 1251 в поток ввода
    SetConsoleOutputCP(1251); // установка кодовой страницы win-cp 1251 в поток вывода
    
   //...
   if (FAILED (WSAStartup (MAKEWORD( 1, 1 ), &ws) ) ) 
   {
      // Error...
      error = WSAGetLastError();
      //...
   }
   
 
   SOCKET mysocket;
  if (INVALID_SOCKET == (mysocket = socket (AF_INET, SOCK_DGRAM,  IPPROTO_UDP) ) )
   {
      // Error...
      error = WSAGetLastError();
      // ... 
   }
  sockaddr_in mysocket_addr;
  ZeroMemory (&mysocket_addr, sizeof (mysocket_addr));
  mysocket_addr.sin_family = AF_INET;
   //адрес сервера. Т.к. TCP/IP представляет адреса в числовом виде, то для перевода 
   // адреса используем функцию inet_addr.
   mysocket_addr.sin_addr.S_un.S_addr = inet_addr ("192.168.1.200"); 
   // Порт. Используем функцию htons для перевода номера порта из обычного в //TCP/IP представление.
   int port;
   std::cout << "ВВедите порт:\r\n";
   std::cin >> port;
   //std::cout << "\n";
   mysocket_addr.sin_port = htons (port); // ЭТО ПОРТ - КУДА СЛАТЬ 
 
   // Дальше выполняем соединение:
   if (SOCKET_ERROR == ( connect (mysocket, (sockaddr *) &mysocket_addr, sizeof (mysocket_addr) ) ) )
   {
      // Error...
      error = WSAGetLastError();
      // ... 
   }
   //формируем данные для перевода 
   //psHELLO = _itoa(53,sHELLO,10); // itoa(a,buffer,radix) а - исходное число, буфер - результат, радикс - система исчисления
   psHELLO = "Sup, board.";
   //кидаем данные на плату
   if (SOCKET_ERROR == ( send (mysocket, psHELLO, sizeof(sHELLO), 0 ) ) )
   {
      // Error...
      error = WSAGetLastError();
      // ... 
   }
   int bytes;
   //и забираем их из буфера в сокете
     if (SOCKET_ERROR == ( bytes = recv (mysocket, (char*) buff, 256, 0 ) ) ) //256 - размер пакета
   {
      // Error...
      error = WSAGetLastError();
      // ... 
   }
   closesocket(mysocket);
   printf("принято %d \n", bytes);
   std::cout << "Принятое значение:\r\n";
   printf("%s", buff );
   std::cin.get(); //эникей
  return 0;
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 3.778 из 5