Ошибка вывода консоли в форму - 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;
}