Отправляет email-рассылки с помощью сервиса Sendsay

RFpro.ru: Microsoft .NET

  Все выпуски  

RusFAQ.ru: .NET


Хостинг Портала RusFAQ.ru:
MosHoster.ru - Профессиональный хостинг на Windows 2008

РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

Чемпионы рейтинга экспертов в этой рассылке

Micren
Статус: Практикант
Рейтинг: 102
∙ повысить рейтинг >>
Evgenijm
Статус: 3-й класс
Рейтинг: 32
∙ повысить рейтинг >>
DrakoN
Статус: Практикант
Рейтинг: 25
∙ повысить рейтинг >>

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / .NET

Выпуск № 127
от 11.04.2009, 15:35

Администратор:Grigory
В рассылке:Подписчиков: 252, Экспертов: 10
В номере:Вопросов: 1, Ответов: 1

Нам важно Ваше мнение об этой рассылке.
Оценить этот выпуск рассылки >>

Вопрос № 164189: Как в Visual NET C++ обратиться к форме из не основного потока ?...


Вопрос № 164.189
Как в Visual NET C++ обратиться к форме из не основного потока ?
Отправлен: 05.04.2009, 16:07
Вопрос задал: Юрий Анатольевич (статус: Посетитель)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Micren
Здравствуйте, Юрий Анатольевич!
Windows Forms используют модель STA(single threaded apartment). Возможно вы уже видели атрибут [STAThreadAttribute]. Это значит, что к компоненту может получать доступ один(и тот же) поток. Единственными методами/свойствами, которые Вы можете использовать из потока не владеющего компонентом являются Invoke(), BeginInvoke(), EndInvoke(), InvokeRequired и CreateGraphics().

Обратите внимание на класс BackgroundWorker. Это асинхронный компонент на базе событий.

Если же Вам уж очень нужно обратится из другого потока к методу контрола то обратите внимание сюда: http://msdn.microsoft.com/ru-ru/library/system.windows.forms.control.invoke.aspx

Вот пример программы, с применением безопасного вызова 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;

private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->butt on1 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(12, 23);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(277, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"Эта метка изменит свойство Text из другого потока";
//
// button1
//
this->button1->Location = System::Drawing::Point(15, 49);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(384, 23);
this->button1->TabIndex = 1;
this->button1->Text = L"Запустить поток изменяющий надпись на метке";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button 1_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(411, 94);
this->Controls->Add(this->button1);
this->Controls->Add(this->label1);
this->MaximizeBox = false;
this->MaximumSize = System::Drawing::Size(427, 130);
this->MinimizeBox = false;
this->MinimumSize = System::Drawing::Size(427, 130);
this->Name = L"Form1";
this->Text = L"Form1";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->ResumeLayout(false);
this->PerformLayout();

}
#pragma endregion
// Обработчик нажатия на кнопку запускающий фоновый поток
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
ThreadPool::QueueUser WorkItem(gcnew WaitCallback(this,&Form1::BackgroundTask),gcnew TaskArgs(this));
}

// Этот метод изменяет надпись на метке
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));
}

int count;

private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
count=0;
}
};
}

main():
Код:

#include "stdafx.h"
#include "Form1.h"

using namespace My164189;

[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 (Россия) | Еще номера >>
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!

    Оценка за ответ: 5


    Вы имеете возможность оценить этот выпуск рассылки.
    Нам очень важно Ваше мнение!
    Оценить этот выпуск рассылки >>

    Отправить вопрос экспертам этой рассылки

    Приложение (если необходимо):

    * Код программы, выдержки из закона и т.п. дополнение к вопросу.
    Эта информация будет отображена в аналогичном окне как есть.

    Обратите внимание!
    Вопрос будет отправлен всем экспертам данной рассылки!

    Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
    экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


    Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
    Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров >>

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2009, Портал RusFAQ.ru, Россия, Москва.
    Авторское право: ООО "Мастер-Эксперт Про"
    Техподдержка портала, тел.: +7 (926) 535-23-31
    Хостинг: "Московский хостер"
    Поддержка: "Московский дизайнер"
    Авторские права | Реклама на портале

    ∙ Версия системы: 5.13 от 01.12.2008

    Яндекс Rambler's Top100
    RusFAQ.ru | MosHoster.ru | MosDesigner.ru
    RusIRC.ru | Kalashnikoff.ru | RadioLeader.ru

    В избранное