Ошибка вывода консоли в форму - C#
Формулировка задачи:
Добрый день ещё раз.
При написании программы возникла следующая проблема. При запуске выскакивает исключение с сообщением типа "Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'txtConsole' не из того потока, в котором он был создан."
исходник:
Так же ругается, что переменная state не определена в текущем контексте, когда доходит до точки вылета в коде переноса в консоль. Вроде отдельный поток создал, разве только что не пытался закрыть его через join, но проблема вроде бы не в этом. Что следует сделать, чтобы не было этого исключения, так как в принципе сообщения в консоль выводятся и внутри функций таких как приведенный выше приём?
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()); } }
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; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д