VC++ .NET UI同步(使用Invoke托管方法),异步线程调用UI

原创 2015年01月28日 22:04:23

花了好几天才学会,之前的代码都是C#的,无法直接使用.


1.首先定义并声明托管

delegate void testUI1(String ^ptr);	//定义一个UI托管
		delegate void testUI2(String ^ptr);	//定义一个UI托管
		testUI1^ myUI1;
		testUI2^ myUI2;

2.在构造函数中实例化托管对象

myUI1 = gcnew testUI1( this, &test::Form1::UI_Test1);
myUI2 = gcnew testUI2( this, &test::Form1::UI_Test2);

3.托管中调用的函数(主要用于UI操作)

void UI_Test1(String ^ptr)  //这个是被线程调用的函数
{
label1->Text=ptr;
}

void UI_Test2(String ^ptr)  //这个是被线程调用的函数
{
label2->Text=ptr;
}

4.在异步线程中使用托管访问UI

		//线程1
		void TestThread(void)
		{
			DWORD i=0;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(1000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI1, ""+i);
				i ++;
				Sleep(1000);
			}
		}


		//线程2
		void TestThread1(void)
		{
			DWORD i=1000;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(2000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI2, ""+i);
				i ++;
				Sleep(1000);
			}
		}




运行效果




附上所有代码

#pragma once

#include "stdafx.h"
#include "windows.h"


#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ws2_32.lib")  
#pragma comment(lib, "User32.lib") 

namespace test {

	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>
	/// Form1 摘要
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{

		System::Threading::Thread  ^Thread1;
		System::Threading::Thread  ^Thread2;

		delegate void testUI1(String ^ptr);	//定义一个UI托管
		delegate void testUI2(String ^ptr);	//定义一个UI托管
		testUI1^ myUI1;
		testUI2^ myUI2;

	public:
		Form1(void)
		{

			InitializeComponent();


			myUI1 = gcnew testUI1( this, &test::Form1::UI_Test1);
			myUI2 = gcnew testUI2( this, &test::Form1::UI_Test2);

			

			this->Thread1 = gcnew Thread (gcnew ThreadStart (this,&test::Form1::TestThread));
			this->Thread1->Start();
			this->Thread1->IsBackground = TRUE;	//将读取线程设置为后台线程,这样在UI线程关闭后可以自动退出
			this->Thread2 = gcnew Thread (gcnew ThreadStart (this,&test::Form1::TestThread1));
			this->Thread2->Start();
			this->Thread2->IsBackground = TRUE;	//将读取线程设置为后台线程,这样在UI线程关闭后可以自动退出
			//
			//TODO: 在此处添加构造函数代码
			//

			this->label1->Text="";
			this->label2->Text="";
		}

		void UI_Test1(String ^ptr)  //这个是被线程调用的函数
		{
			this->label1->Text=ptr;
		}

		void UI_Test2(String ^ptr)  //这个是被线程调用的函数
		{
			this->label2->Text=ptr;
		}

		//线程1
		void TestThread(void)
		{
			DWORD i=0;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(1000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI1, ""+i);
				i ++;
				Sleep(1000);
			}
		}


		//线程2
		void TestThread1(void)
		{
			DWORD i=1000;

			//防止在窗口句柄初始化之前就走到下面的代码
			while (!this->IsHandleCreated)
			{
				Sleep(10);
			}

			//Sleep(2000);	//一定要延时之后再建立线程,否则会出现
			//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
			//主要是因为UI界面还没有初始化完成,调用Invoke会出错
			while(1)
			{
				this->Invoke(myUI2, ""+i);
				i ++;
				Sleep(1000);
			}
		}

	protected:
		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Label^  label1;
	protected: 
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Button^  button1;

	private:
		/// <summary>
		/// 必需的设计器变量。
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// 设计器支持所需的方法 - 不要
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		void InitializeComponent(void)
		{
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Font = (gcnew System::Drawing::Font(L"宋体", 20, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(134)));
			this->label1->ForeColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(0)), static_cast<System::Int32>(static_cast<System::Byte>(0)), 
				static_cast<System::Int32>(static_cast<System::Byte>(192)));
			this->label1->Location = System::Drawing::Point(106, 64);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(96, 27);
			this->label1->TabIndex = 0;
			this->label1->Text = L"label1";
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Font = (gcnew System::Drawing::Font(L"宋体", 20, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(134)));
			this->label2->ForeColor = System::Drawing::Color::Red;
			this->label2->Location = System::Drawing::Point(109, 139);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(96, 27);
			this->label2->TabIndex = 1;
			this->label2->Text = L"label2";
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(216, 226);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(75, 23);
			this->button1->TabIndex = 2;
			this->button1->Text = L"button1";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(503, 288);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->label1);
			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 Form1_Load(System::Object^  sender, System::EventArgs^  e) {
			 }
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
				 this->label1->Text = "按下按钮";
				 this->label2->Text = "按下按钮";
			 }
};
}



托管C++

本文转自http://www.cnblogs.com/pursue/articles/1992324.html,如有侵权,请联系删除 原文请看(这里) 简介  你好,欢迎光临本人关于.NET编程...
  • yuhai738639
  • yuhai738639
  • 2017-09-05 14:22:35
  • 809

WinForms程序使用委托(Invoke)的方式操作界面的控件

在WinForms程序开发中,有时使用多线程或者异步处理比较耗时的数据,处理完成后需要把结果反馈到程序界面上,这是就需要操作WinForms程序的界面控件了。 如果直接操作的话,则会出现以下错误 注:...
  • yuanhong55
  • yuanhong55
  • 2013-11-08 09:39:43
  • 1617

C#后台线程和UI的交互

在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了,特别是要用类似进度条来实时显...
  • u012252959
  • u012252959
  • 2015-11-18 09:29:52
  • 1401

c#异步调用和回调

C#异步委托(异步方法调用)一: 同步调用 : 程序顺序执行时-->调用很耗时的[方法]-->阻塞当前线程-->[方法]调用完成-->继续执行。 异步调用 : ------------------...
  • u012988972
  • u012988972
  • 2015-08-14 16:20:51
  • 4608

C# 委托的三种调用示例(同步调用 异步调用 异步回调)

本文将主要通过同步调用、异步调用、异步回调三个示例来讲解在用委托执行同一个加法类的时候的的区别和利弊 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ...
  • xxy0403
  • xxy0403
  • 2016-05-21 12:29:43
  • 495

winform异步线程更新UI问题

刚才看到有人问为了winfrom中,在大数据绑定的时候出现画面假死的状态,为了解决这个问题希望通过再开一个线程来给控件绑定数据,可是画面还是会假死。 现在看到的方法有 1.掩耳盗铃法(Contro...
  • cqkxzyi
  • cqkxzyi
  • 2014-03-23 22:13:15
  • 1589

C#委托主线程调用控件并且同步UI界面显示以及协议制作

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin...
  • yangganglone
  • yangganglone
  • 2015-03-09 16:06:24
  • 545

C#(同步调用、异步调用、异步回调)

文章来源:http://blog.csdn.net/wanlong360599336/article/details/8781477 using System;   using Syste...
  • u012546338
  • u012546338
  • 2017-03-30 10:56:24
  • 1099

c# 异步调用 BeginInvoke与EndInvoke方法

为什么要进行异步回调?众所周知,普通方法运行,是单线程的,如果中途有大型操作(如:读取大文件,大批量操作数据库,网络传输等),都会导致方法阻塞,表现在界面上就是,程序卡或者死掉,界面元素不动了,不响应...
  • aoshilang2249
  • aoshilang2249
  • 2015-01-25 19:23:51
  • 6018

Invoke和BeginInvoke的使用(转载)

在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate。  一、为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的...
  • codepython
  • codepython
  • 2014-07-03 13:29:07
  • 832
收藏助手
不良信息举报
您举报文章:VC++ .NET UI同步(使用Invoke托管方法),异步线程调用UI
举报原因:
原因补充:

(最多只允许输入30个字)