У меня есть класс MainForm (как и следовало ожидать, это форма), на котором есть текстовое поле. У меня также есть еще один класс под названием «Application_Server». Это делает загрузку другого материала (не только связанного с фоном, довольно много сетевого материала и т. Д.).C++ CLI Invoke issues
Класс Application_Server запускается в собственном потоке, но для обновления элементов управления в форме для этого вопроса мы будем придерживаться только текстового поля.
Проблема заключается в том, что даже если я выполнить команду, чтобы установить текст элемента управления TextBox с помощью «Invoke» Я до сих пор получаю следующее исключение во время выполнения:
Дополнительная информация: операции кросс-нить Недействительно: Управление 'DebugTextBox', доступ к которому осуществляется из потока, отличного от потока, который был создан .
Что может быть причиной этого? Я определенно приглашаю делегата в MainForm.
Вот соответствующие сегменты кода (вырублены для удобства чтения):
MainForm.h:
public ref class MainForm : public System::Windows::Forms::Form {
delegate void del_updateDebugText(String^ msg);
del_updateDebugText^ updateDebugText = gcnew del_updateDebugText(this, &MainForm::postDebugMessage);
private: void postDebugMessage(String^ message);
};
MainForm.cpp:
void EagleEye_Server::MainForm::postDebugMessage(String^ message)
{
Monitor::Enter(DebugTextBox);
if (this->DebugTextBox->InvokeRequired)
{
this->Invoke(updateDebugText, gcnew array<Object^> { message });
}
else
{
this->DebugTextBox->AppendText(message);
}
Monitor::Exit(DebugTextBox);
}
И, наконец, код, вызывающий его :
void ServerAppManager::postDebugMessage(System::String^ message)
{
mainFormHandle->updateDebugText(message);
}
void ServerAppManager::applicationStep()
{
postDebugMessage("Starting\n");
// This is Run in seperate thread in MainForm.cpp
while (s_appState == ApplicationState::RUN)
{
postDebugMessage("Testing\n");
}
}
Спасибо!
Все кажется прекрасным, но вы вызываете 'Invoke()' с 'MainForm', а не' TextBox'. Вы можете попробовать вызвать 'Invoke()' с помощью 'TextBox', чтобы узнать, помогает ли это. Если это исправлено, это означает, что «TextBox» мог быть создан в другом потоке из «MainForm», что не кажется правильным. – Andy
Не будет ли этот код заторможен? Вызов 'Invoke()' приведет к вызову 'postDebugMessage()' в потоке пользовательского интерфейса, что вызовет его ожидание на 'DebugTextBox', который удерживается вызывающим потоком ... – Medinoc
Да, действительно, он зашел в тупик , из интереса, как бы вы сделали это аккуратно, чтобы этого не случилось? Мой пример ниже (нажатие вызова Invoke другому объекту, вызывающему метод) кажется беспорядочным, например, что, если я забыл вызвать? –