Отвечает: Micren
Здравствуйте, Юрий Анатольевич! Windows Forms используют модель STA(single threaded apartment). Возможно вы уже видели атрибут [STAThreadAttribute]. Это значит, что к компоненту может получать доступ один(и тот же) поток. Единственными методами/свойствами, которые Вы можете использовать из потока не владеющего компонентом являются Invoke(), BeginInvoke(), EndInvoke(), InvokeRequired и CreateGraphics().
Обратите внимание на класс BackgroundWorker. Это асинхронный компонент на базе событий.
Вот пример программы, с применением безопасного вызова Invoke(): Form1.h
Код:
#pragma once
namespace My164189 {
using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Threading;
/// <summary> /// Summary for Form1 /// /// WARNING: If you change the name of this class,
you will need to change the /// 'Resource File Name' property for the managed resource compiler tool /// associated with all .resx files this class depends on. Otherwise, /// the designers will not be able to interact properly with localized /// resources associated with this form. /// </summary> public ref class Form1 : public System::Windows::Forms::F
orm { public: Form1(void) { InitializeComponent(); // //TODO: Add the constructor code here // }
protected: /// <summary> /// Clean up any resources being used. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Label^ label1; protected: private: System::Windows::Forms::Button^ button1;
// Этот метод изменяет надпись на метке void ChangeLabel() { label1->Text=String::Format(L"На кнопку нажали {0} раз",++count); }
// Делегат соответствующий вызываемому методу delegate void ChangeLabelDelegate();
// Это класс для передачи параметра задаче ref class TaskArgs { public: // Передаем ссылку на форму
TaskArgs(Form1^ form) { this->form=form; } property Form1^ MyForm { Form1^ get(){return form;} } private: Form1^ form; };
void BackgroundTask(Object^ o) { TaskArgs^ args=(TaskArgs^)o; // Если раскомментировать следующую строку, то при асинхронном вызове будет исключение // args->MyForm->ChangeLabel(); // Безопасный вызов a
rgs->MyForm->Invoke(gcnew ChangeLabelDelegate(args->MyForm,&Form1::ChangeLabel)); }
[STAThreadAttribute] int main(array<System::String ^> ^args) { // Enabling Windows XP visual effects before any controls are created Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it Application::Run(gcnew Form1()); return 0; }
К ответу
прикреплен файл с приложением для MS VS 2008.
Все же следует сказать. Что подобных "фокусов" лучше избегать. В 99.9% можно и нужно обходиться без подобных вещей. Иначе Ваш код будет жестко связан с формой и это чревато возникновением трудностей при модификации программы и ошибок в ее работе при не аккуратном программировании.
Многопоточность вообще требует очень тщательного планирования и аккуратности в реализации. На первых порах постарайтесь обойтись без нее везде, где это возможно.
Попробуйте сначала понять основы программирования под .NET, а не лезьте в дебри. Всему свое время.
Так же рекомендую, при программировании под .NET, вместо C++ использовать C#. Этот язык изначально ориентирован на .NET и код программы получается проще, лаконичнее и нагляднее.
Желаю удачи.
Прикреплённый файл: Загрузить >> Срок хранения файла на сервере RusFAQ.ru составляет 30 суток с момента отправки ответа.
Ответ отправил: Micren (статус: Практикант)
Ответ отправлен: 05.04.2009, 22:47
Как сказать этому эксперту "спасибо"?
Отправить SMS
#thank 246879 на номер 1151 (Россия) | Еще номера >>
Вам помогли? Пожалуйста, поблагодарите эксперта за это!
Оценка за ответ: 5
Скажите "спасибо" эксперту, который помог Вам!
Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
на короткий номер 1151 (Россия)
Номер ответа и конкретный текст СМС указан внизу каждого ответа.
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.