序列化和反序列化

序列化和反序列化

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Xml;

using System.Xml.Serialization;

using System.IO;

 

namespace ConsoleApplication8

{


public
class
XMLWrite

{

 


static
void Main(string[] args)

{

WriteXML();

}

 


public
class
Book

{


public
String title;

}

 


public
static
void WriteXML()

{


Book overview = new
Book();

overview.title = “Serialization Overview”;

 


XmlSerializer writer = new
XmlSerializer(typeof(Book));


string path = @”C:\Users\xudajun\Desktop\test” + @”\SerializationOverview.xml”;


FileStream file = File.Create(path);

writer.Serialize(file, overview);

file.Close();

 


XmlSerializer reader = new
XmlSerializer(typeof(Book));


StreamReader f =new
StreamReader(path);


Book book1 = (Book)reader.Deserialize(f);

f.Close();

 


Console.WriteLine(book1.title);

}

}

}

 

 

 

 

 

文件递归遍历

文件递归遍历

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.IO;

 

namespace ConsoleApplication6

{


class
Program

{


static
void Main(string[] args)

{

getFiles(@”C:\Users\xudajun\Desktop\S7200″);

}

 


private
static
void getFiles(string path)

{


string[] strFileName = Directory.GetFiles(path);


string[] strDirectories = Directory.GetDirectories(path);

 


foreach(string i in strFileName)

{


Console.WriteLine(i);

}


foreach(string i in strDirectories)

{


Console.WriteLine(i);

getFiles(i);

}

 

}

}

 

}

 

程序间以太网通讯

演示两个程序之间的通信

服务器

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using System.Net.Sockets;

using System.Net;

using System.Threading;

 

namespace ConsoleApplication5

{


class
Program

{


private
static
byte[] result = new
byte[1024];


private
static
int myProt = 8885; //端口


static
Socket serverSocket;


static
void Main(string[] args)

{


//服务器IP地址


IPAddress ip = IPAddress.Parse(“127.0.0.1”);

serverSocket = new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

serverSocket.Bind(new
IPEndPoint(ip, myProt)); //绑定IP地址,端口

serverSocket.Listen(10); //设定最多10个排队连接请求


Console.WriteLine(启动监听{0}成功, serverSocket.LocalEndPoint.ToString());


//通过Clientsoket发送数据


Thread myThread = new
Thread(ListenClientConnect);

myThread.Start();

}

 


///
<summary>


///
监听客户端连接


///
</summary>


private
static
void ListenClientConnect()

{


while (true)

{


Socket clientSocket = serverSocket.Accept();//线程阻塞,每当有新的连接,消除阻塞

clientSocket.Send(Encoding.Unicode.GetBytes(连接成功!));


Thread receiveThread = new
Thread(ReceiveMessage);

receiveThread.Start(clientSocket);

}

}

 


///
<summary>


///
接收消息


///
</summary>


///
<param name=”clientSocket“></param>


private
static
void ReceiveMessage(object clientSocket)

{


Socket myClientSocket = (Socket)clientSocket;


while (true)

{


try

{


//通过clientSocket接收数据


int receiveNumber = myClientSocket.Receive(result);


Console.WriteLine(接收客户端{0}消息{1}”, myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));

}


catch (Exception ex)

{


Console.WriteLine(ex.Message);

myClientSocket.Shutdown(SocketShutdown.Both);

myClientSocket.Close();


break;

}

}

}

}

}

 

客户端

using System;

using System.Text;

 

using System.Net;

using System.Net.Sockets;

using System.Threading;

 

namespace ConsoleApplication6

{


class
Program

{


private
static
byte[] result = new
byte[1024];


static
void Main(string[] args)

{


//设定服务器IP地址


IPAddress ip = IPAddress.Parse(“127.0.0.1”);


Socket clientSocket = new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


try

{

clientSocket.Connect(new
IPEndPoint(ip, 8885)); //配置服务器IP与端口


Console.WriteLine(连接服务器成功);

}


catch

{


Console.WriteLine(连接服务器失败,请按回车键退出!);


return;

}


//通过clientSocket接收数据


int receiveLength = clientSocket.Receive(result);


Console.WriteLine(接收服务器消息:{0}”, Encoding.Unicode.GetString(result, 0, receiveLength));


//通过 clientSocket 发送数据


//for (int i = 0; i < 10; i++)


//{


// try


// {


// Thread.Sleep(1000); //等待1秒钟


// string sendMessage = “client send Message Hellp” + DateTime.Now;


// clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));


// Console.WriteLine(“向服务器发送消息:{0}” + sendMessage);


// }


// catch


// {


// clientSocket.Shutdown(SocketShutdown.Both);


// clientSocket.Close();


// break;


// }


//}


while (true)

{


try

{


string sendMessage = Console.ReadLine()+ DateTime.Now;

clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));

}


catch

{

clientSocket.Shutdown(SocketShutdown.Both);

clientSocket.Close();


break;

}

}


Console.WriteLine(发送完毕,按回车键退出);


Console.ReadLine();

}

}

}

 

上位机发送数据给PLC S71200

客户端

上位机发送数据给PLC S71200(后续删除此处示例)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using System.Net;

using System.Net.Sockets;

using System.Threading;

 

namespace ConsoleApplication4

{


class
Program

{


static
void Main(string[] args)

{


IPAddress ip = IPAddress.Parse(“192.168.0.1”);


Socket clientSocket = new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp );


try

{

clientSocket.Connect(new
IPEndPoint(ip,2000));


Console.WriteLine(服务器连接成功!”);

}


catch

{


Console.WriteLine(服务器连接失败!);


return;

}


byte[] sendmessage = new
byte[10];


for (int i= 0;i< 10;++i)

{

sendmessage[i] = Convert.ToByte(i);

}

clientSocket.Send(sendmessage);

clientSocket.Close();

 

}

}

}

 

DOS对内存的分配

 

8088/8086系统中,有些内存区域的作用是固定的,用户不能随便使用,如:

  • 中断矢量区:00000H—003FFH共1K字节,用以存放256种中断类型的中断矢量,每个中断矢量占用4个字节,共256×4=1024=1K;
  • 显示缓冲区:B0000H—B0F9FH约4000(25×80×2)字节,是单色显示器 的显示缓冲区,存放文本方式下,所显示字符的ASCII码及属性码;B8000H—BBF3FH约16K字节,是彩色显示器的显示缓冲区,存放图形方式下,屏幕显示象素的代码。
  • 启动区:FFFF0H—FFFFFH共16个单元,用以存放一条无条件转移指令的代码,转移到系统的初始化部分。

串口采集

串口通讯时,数据的接收方为了保证数据接收不出现错误。通常会采用传输速率的数倍(如16倍64倍)的时钟采样传输过来的信号。如采用16倍的时钟信号,起始位开始后,用时钟脉冲计数8次,表示已经到达起始位的中间,采样起始位,以后每隔16个时钟采样一次,即在每隔信息位的中心处采样,这样即使发送时钟与接收时钟略有差异,也能保证接收的正确。

树形结构

 

双亲表示法

Public Const MaxSize As Integer = 10

 

Public Type pnode

info As String

parent As Integer

End Type

 

Public Type ptree

data(0 To MaxSize – 1) As pnode

num As Integer ‘树当前中的节点数目

End Type

 

Private Sub CommandButton1_Click()

Dim tree As ptree

tree.num = 8

tree.data(0).info = “a”

tree.data(0).parent = -1

tree.data(1).info = “b”

tree.data(1).parent = 0

tree.data(2).info = “c”

tree.data(2).parent = 0

tree.data(3).info = “d”

tree.data(3).parent = 0

tree.data(4).info = “e”

tree.data(4).parent = 1

tree.data(5).info = “f”

tree.data(5).parent = 1

tree.data(6).info = “g”

tree.data(6).parent = 3

tree.data(7).info = “h”

tree.data(7).parent = 4

End Sub

 

孩子表示法

 

双亲孩子表示法

 

孩子兄弟表示法

非精准定时器 延时器

非精准定时,延时器

#include”reg51.h”

#include”intrins.h”

 

#define ST_0_5S 2601

#define ST_1S 5201

 

bit Delay0Open=0;

unsigned long Delay0Counter=0;

bit Delay0Over=0;

 

void main()

{

    Delay0Counter=ST_0_5S;

    Delay0Open=1;

 

    while(1)

    {

        if (Delay0Open)

        {

            if(Delay0Counter)

            {

                Delay0Counter–;

                if(!Delay0Counter)

                {

                    Delay0Over=1;

                }

            }

        }

        if(_testbit_(Delay0Over))

        {

            Delay0Counter=ST_0_5S;

            P2=~P2;

        }

    }

}

延时器的扩展

#include”reg51.h”

#include”intrins.h”

 

#define ST_0_5S 2601

#define ST_1S (ST_0_5S+ST_0_5S)

 

bit Delay0Open=0;

unsigned long Delay0Counter=0;

bit Delay0Over=0;

 

bit Delay1Open=0;

unsigned long Delay1Counter=0;

bit Delay1Over=0;

 

void main()

{

    Delay0Counter=ST_0_5S;

    Delay0Open=1;

 

    Delay1Counter=ST_1S;

    Delay1Open=1;

 

    while(1)

    {

        if (Delay0Open)

        {

            if(Delay0Counter)

            {

                Delay0Counter–;

                if(!Delay0Counter)

                {

                    Delay0Over=1;

                }

            }

        }

        if(_testbit_(Delay0Over))

        {

            Delay0Counter=ST_0_5S;

            P2=~P2;

        }

 

        if (Delay1Open)

        {

            if(Delay1Counter)

            {

                Delay1Counter–;

                if(!Delay1Counter)

                {

                    Delay1Over=1;

                }

            }

        }

        if(_testbit_(Delay1Over))

        {

            Delay1Counter=ST_1S;

            P3=~P3;

        }

    }

}

 

 

 

 

 

模拟多任务多线程程序

最简单的操作系统

#include
“stdio.h”

 

int main()

{

    while(1)

    {

        ;

    }


return 0;

}

实现一个程序

#include
“stdio.h”

#include
“stdlib.h”

 

//计算y=3×2+7abx+c

 

const
unsigned
char a = 9;

const
unsigned
char b = 7;

const
unsigned
char c = 18;

 

int main()

{

    bool isTask_1_Living = 1;//任务标志位

 

    unsigned
int x;

    unsigned
long y, z;

 

    while(1)

    {

        if(isTask_1_Living)

        {

            x = rand();

            y = 3;

            y *= x;

            y *= x;

            z = 7;

            z *= a;

            z *= b;

            z *= x;

            y += z;

            y += c;

            isTask_1_Living = 0;

            printf(“%d”, y);

        }

    }


return 0;

}

把任务分成多个线程

#include
“stdio.h”

#include
“stdlib.h”

 

//计算y=3×2+7abx+c

 

const
unsigned
char a = 9;

const
unsigned
char b = 7;

const
unsigned
char c = 18;

 

int main()

{

    bool isTask_1_Living = 1;//任务标志位

    unsigned
char Task1_Thread_Progress = 0;//划分线程

 

    unsigned
int x;

    unsigned
long y, z;

 

    while(1)

    {

        if(isTask_1_Living)

        {

            switch (Task1_Thread_Progress)

            {

                case 0:

                    x = rand();

                    y = 3;

                    break;

                case 1:

                    y *= x;

                    y *= x;

                    break;

                case 2:

                    z = 7;

                    z *= a;

                    break;

                case 3:

                    z *= b;

                    z *= x;

                    break;

                case 4:

                    y += z;

                    y += c;

                    isTask_1_Living = 0;

                    printf(“%d”, y);

                    break;

            }

            Task1_Thread_Progress++;

            if(Task1_Thread_Progress>4)

            {

                Task1_Thread_Progress = 0;

            }            

        }

    }


return 0;

}

多任务

#include
“stdio.h”

#include
“stdlib.h”

 

//计算y1=3×12+7a1b1x+c1

//计算y2=3×22+7a2b2x+c2

 

const
unsigned
char a1 = 9;

const
unsigned
char b1 = 7;

const
unsigned
char c1 = 18;

 

const
unsigned
char a2 = 4;

const
unsigned
char b2 = 13;

const
unsigned
char c2 = 6;

 

int main()

{

    bool isTask_1_Living = 1;//任务1标志位

    unsigned
char Task1_Thread_Progress = 0;//划分线程

 

    bool isTask_2_Living = 1;//任务2标志位

    unsigned
char Task2_Thread_Progress = 0;//划分线程

 

    unsigned
int x1;

    unsigned
long y1, z1;

 

    unsigned
int x2;

    unsigned
long y2, z2;

 

 

    while(1)

    {

        if(isTask_1_Living)

        {

            switch (Task1_Thread_Progress)

            {

                case 0:

                    x1 = 1;// rand();

                    y1 = 3;

                    break;

                case 1:

                    y1 *= x1;

                    y1 *= x1;

                    break;

                case 2:

                    z1 = 7;

                    z1 *= a1;

                    break;

                case 3:

                    z1 *= b1;

                    z1 *= x1;

                    break;

                case 4:

                    y1 += z1;

                    y1 += c1;

                    isTask_1_Living = 0;

                    printf(“%d\n”, y1);

                    break;

            }

            Task1_Thread_Progress++;

            if(Task1_Thread_Progress>4)

            {

                Task1_Thread_Progress = 0;

            }            

        }

        if (isTask_2_Living)

        {

            switch (Task2_Thread_Progress)

            {

            case 0:

                x2 = 1;// rand();

                y2 = 3;

                break;

            case 1:

                y2 *= x2;

                y2 *= x2;

                break;

            case 2:

                z2 = 7;

                z2 *= a2;

                break;

            case 3:

                z2 *= b2;

                z2 *= x2;

                break;

            case 4:

                y2 += z2;

                y2 += c2;

                isTask_2_Living = 0;

                printf(“%d\n”, y2);

                break;

            }

            Task2_Thread_Progress++;

            if (Task2_Thread_Progress>4)

            {

                Task2_Thread_Progress = 0;

            }

        }

    }


return 0;

}

数据代码分离

#include
“stdio.h”

#include
“stdlib.h”

 

//计算y1=3×12+7a1b1x+c1

//计算y2=3×22+7a2b2x+c2

 

struct
_coefficient

{

    unsigned
int a;

    unsigned
int b;

    unsigned
int c;

};

struct
_variable

{

    unsigned
int x;

    unsigned
int y;

    unsigned
int z;

};

struct
myTask

{

    _coefficient CO;

    _variable V;

 

};

 

//线程常量定义

#define
THREAD_OVER -1            //线程结束

#define
THREAD_NOTOVER 0        //线程未结束

 

char myThread(myTask* Task,unsigned
char *Process)

{

    char ret = 0;

 

    switch (*Process)

    {

        case 0:

            (*Task).V.x = 1;// rand();

            (*Task).V.y = 3;

            break;

        case 1:

            (*Task).V.y *= (*Task).V.x;

            (*Task).V.y *= (*Task).V.x;

            break;

        case 2:

            (*Task).V.z = 7;

            (*Task).V.z *= (*Task).CO.a;

            break;

        case 3:

            (*Task).V.z *= (*Task).CO.b;

            (*Task).V.z *= (*Task).V.x;

            break;

        case 4:

            (*Task).V.y += (*Task).V.z;

            (*Task).V.y += (*Task).CO.c;

            printf(“%d\n”, (*Task).V.y);

            break;

    }

    (*Process)++;

    if (*Process>4)

    {

        ret = -1;//线程结束

        *Process = 0;

    }

    return ret;

}

 

//定义任务

myTask Task1, Task2;

 

void InitTask(myTask *Task,unsigned
char
a1,unsigned
char
b1,unsigned
char
c1)

{

    (*Task).CO.a = a1;

    (*Task).CO.b = b1;

    (*Task).CO.c = c1;

}

 

int main()

{

    bool isTask_1_Living = 1;//任务1标志位

    unsigned
char Task1_Thread_Progress = 0;//划分线程

 

    bool isTask_2_Living = 1;//任务2标志位

    unsigned
char Task2_Thread_Progress = 0;//划分线程

 

    InitTask(&Task1, 9, 7, 18);

    InitTask(&Task2, 4, 13, 16);

 

    //printf(“%d\n”,Task1.CO.a);

 

    while(1)

    {

        if(isTask_1_Living)

        {

            isTask_1_Living = !myThread(&Task1,&Task1_Thread_Progress);

        }

        if (isTask_2_Living)

        {

            isTask_2_Living = !myThread(&Task2, &Task2_Thread_Progress);

        }

    }

 


return 0;

}

线程的另一种生死

#include
“stdio.h”

#include
“stdlib.h”

 

//计算y1=3×12+7a1b1x+c1

//计算y2=3×22+7a2b2x+c2

//计算y3=3×32+7a3b3x+c3

struct
_coefficient

{

    unsigned
int a;

    unsigned
int b;

    unsigned
int c;

};

struct
_variable

{

    unsigned
int x;

    unsigned
int y;

    unsigned
int z;

};

struct
myTask

{

    _coefficient CO;

    _variable V;

 

};

 

//线程常量定义

#define
THREAD_OVER -1            //线程结束

#define
THREAD_NOTOVER 0        //线程未结束

 

char myThread(myTask* Task,unsigned
char *Process)

{

    char ret = 0;

 

    switch (*Process)

    {

        case 0:

            (*Task).V.x = 1;// rand();

            (*Task).V.y = 3;

            break;

        case 1:

            (*Task).V.y *= (*Task).V.x;

            (*Task).V.y *= (*Task).V.x;

            break;

        case 2:

            (*Task).V.z = 7;

            (*Task).V.z *= (*Task).CO.a;

            break;

        case 3:

            (*Task).V.z *= (*Task).CO.b;

            (*Task).V.z *= (*Task).V.x;

            break;

        case 4:

            (*Task).V.y += (*Task).V.z;

            (*Task).V.y += (*Task).CO.c;

            printf(“%d\n”, (*Task).V.y);

            break;

    }

    (*Process)++;

    if (*Process>4)

    {

        ret = -1;//线程结束

        *Process = 0;

    }

    return ret;

}

 

//定义任务

myTask Task1, Task2, Task3;

 

void InitTask(myTask *Task,unsigned
char
a1,unsigned
char
b1,unsigned
char
c1)

{

    (*Task).CO.a = a1;

    (*Task).CO.b = b1;

    (*Task).CO.c = c1;

}

 

int main()

{

    bool isTask_1_Living = 1;//任务1标志位

    unsigned
char Task1_Thread_Progress = 0;//划分线程

 

    bool isTask_2_Living = 1;//任务2标志位

    unsigned
char Task2_Thread_Progress = 0;//划分线程

 

    unsigned isTask_3_Living = 5;//任务3标志位

    unsigned
char Task3_Thread_Progress = 0;//划分线程

 

    InitTask(&Task1, 9, 7, 18);

    InitTask(&Task2, 4, 13, 16);

    InitTask(&Task3, 2, 24, 3);

 

    //printf(“%d\n”,Task1.CO.a);

 

    while(1)

    {

        if(isTask_1_Living)

        {

            isTask_1_Living = !myThread(&Task1,&Task1_Thread_Progress);

        }

        if (isTask_2_Living)

        {

            isTask_2_Living = !myThread(&Task2, &Task2_Thread_Progress);

        }

        if (isTask_3_Living)//程序会执行五次

        {

            isTask_3_Living +=myThread(&Task3, &Task3_Thread_Progress);

        }

    }

 


return 0;

}

 

 

 

 

 

 

 

定时器扩展

定时器的扩展

#include”reg51.h”

#include”intrins.h”

 

#define ST_0_5S     2500

#define ST_1S     5000

#define ST_1_5S     7500

#define ST_2S     10000

#define ST_2_5S     12500

#define ST_3S     15000

#define ST_3_5S     17500

#define ST_4S     20000

 

sbit LED1=P2^0;

sbit LED2=P2^1;

sbit LED3=P2^2;

sbit LED4=P2^3;

sbit LED5=P2^4;

sbit LED6=P2^5;

sbit LED7=P2^6;

sbit LED8=P2^7;

 

bit SoftTimer0Enable=0;

unsigned int SoftTimer0Counter=0;

bit SoftTimer0Over=0;

 

bit SoftTimer1Enable=0;

unsigned int SoftTimer1Counter=0;

bit SoftTimer1Over=0;

 

bit SoftTimer2Enable=0;

unsigned int SoftTimer2Counter=0;

bit SoftTimer2Over=0;

 

bit SoftTimer3Enable=0;

unsigned int SoftTimer3Counter=0;

bit SoftTimer3Over=0;

 

bit SoftTimer4Enable=0;

unsigned int SoftTimer4Counter=0;

bit SoftTimer4Over=0;

 

bit SoftTimer5Enable=0;

unsigned int SoftTimer5Counter=0;

bit SoftTimer5Over=0;

 

bit SoftTimer6Enable=0;

unsigned int SoftTimer6Counter=0;

bit SoftTimer6Over=0;

 

bit SoftTimer7Enable=0;

unsigned int SoftTimer7Counter=0;

bit SoftTimer7Over=0;

 

void main(void)

{

    TMOD=0x02;//定时器工作方式2,自装

    TH0=TL0=0x38;//设定硬件时基0.2ms

    ET0=1;

    TR0=1;

    EA=1;

 

    SoftTimer0Counter=ST_0_5S;

    SoftTimer0Enable=1;

    SoftTimer1Counter=ST_1S;

    SoftTimer1Enable=1;

    SoftTimer2Counter=ST_1_5S;

    SoftTimer2Enable=1;

    SoftTimer3Counter=ST_2S;

    SoftTimer3Enable=1;

    SoftTimer4Counter=ST_2_5S;

    SoftTimer4Enable=1;

    SoftTimer5Counter=ST_3S;

    SoftTimer5Enable=1;

    SoftTimer6Counter=ST_3_5S;

    SoftTimer6Enable=1;

    SoftTimer7Counter=ST_4S;

    SoftTimer7Enable=1;

 

    while(1)

    {

        if(_testbit_(SoftTimer0Over))

        {

             SoftTimer0Counter=ST_0_5S;

             LED1=~LED1;

        }

        if(_testbit_(SoftTimer1Over))

        {

             SoftTimer1Counter=ST_1S;

             LED2=~LED2;

        }

        if(_testbit_(SoftTimer2Over))

        {

             SoftTimer2Counter=ST_1_5S;

             LED3=~LED3;

        }

        if(_testbit_(SoftTimer3Over))

        {

             SoftTimer3Counter=ST_2S;

             LED4=~LED4;

        }

        if(_testbit_(SoftTimer4Over))

        {

             SoftTimer4Counter=ST_2_5S;

             LED5=~LED5;

        }

        if(_testbit_(SoftTimer5Over))

        {

             SoftTimer5Counter=ST_3S;

             LED6=~LED6;

        }

        if(_testbit_(SoftTimer6Over))

        {

             SoftTimer6Counter=ST_3_5S;

             LED7=~LED7;

        }

        if(_testbit_(SoftTimer7Over))

        {

             SoftTimer7Counter=ST_4S;

             LED8=~LED8;

        }

    }

}

 

void TimerBaseByTimer0(void) interrupt 1

{

    if(SoftTimer0Enable)

    {

        if(SoftTimer0Counter)

        {

            SoftTimer0Counter–;

            if(!SoftTimer0Counter)

            {

                SoftTimer0Over=1;

            }

        }

    }

    if(SoftTimer1Enable)

    {

        if(SoftTimer1Counter)

        {

            SoftTimer1Counter–;

            if(!SoftTimer1Counter)

            {

                SoftTimer1Over=1;

            }

        }

    }

    if(SoftTimer2Enable)

    {

        if(SoftTimer2Counter)

        {

            SoftTimer2Counter–;

            if(!SoftTimer2Counter)

            {

                SoftTimer2Over=1;

            }

        }

    }

    if(SoftTimer3Enable)

    {

        if(SoftTimer3Counter)

        {

            SoftTimer3Counter–;

            if(!SoftTimer3Counter)

            {

                SoftTimer3Over=1;

            }

        }

    }

    if(SoftTimer4Enable)

    {

        if(SoftTimer4Counter)

        {

            SoftTimer4Counter–;

            if(!SoftTimer4Counter)

            {

                SoftTimer4Over=1;

            }

        }

    }

    if(SoftTimer5Enable)

    {

        if(SoftTimer5Counter)

        {

            SoftTimer5Counter–;

            if(!SoftTimer5Counter)

            {

                SoftTimer5Over=1;

            }

        }

    }

    if(SoftTimer6Enable)

    {

        if(SoftTimer6Counter)

        {

            SoftTimer6Counter–;

            if(!SoftTimer6Counter)

            {

                SoftTimer6Over=1;

            }

        }

    }

    if(SoftTimer7Enable)

    {

        if(SoftTimer7Counter)

        {

            SoftTimer7Counter–;

            if(!SoftTimer7Counter)

            {

                SoftTimer7Over=1;

            }

        }

    }

}

 

 

 

 

 

上述程序的简化版,去除了使能条件

#include”reg51.h”

#include”intrins.h”

 

#define ST_0_5S     2500

#define ST_1S     5000

#define ST_1_5S     7500

#define ST_2S     10000

#define ST_2_5S     12500

#define ST_3S     15000

#define ST_3_5S     17500

#define ST_4S     20000

 

sbit LED1=P2^0;

sbit LED2=P2^1;

sbit LED3=P2^2;

sbit LED4=P2^3;

sbit LED5=P2^4;

sbit LED6=P2^5;

sbit LED7=P2^6;

sbit LED8=P2^7;

 

unsigned int SoftTimer0Counter=0;

bit SoftTimer0Over=0;

 

unsigned int SoftTimer1Counter=0;

bit SoftTimer1Over=0;

 

unsigned int SoftTimer2Counter=0;

bit SoftTimer2Over=0;

 

unsigned int SoftTimer3Counter=0;

bit SoftTimer3Over=0;

 

unsigned int SoftTimer4Counter=0;

bit SoftTimer4Over=0;

 

unsigned int SoftTimer5Counter=0;

bit SoftTimer5Over=0;

 

unsigned int SoftTimer6Counter=0;

bit SoftTimer6Over=0;

 

unsigned int SoftTimer7Counter=0;

bit SoftTimer7Over=0;

 

void main(void)

{

    TMOD=0x02;//定时器工作方式2

    TH0=TL0=0x38;//设定硬件时基0.2ms

    ET0=1;

    TR0=1;

    EA=1;

 

    SoftTimer0Counter=ST_0_5S;

    SoftTimer1Counter=ST_1S;

    SoftTimer2Counter=ST_1_5S;

    SoftTimer3Counter=ST_2S;

    SoftTimer4Counter=ST_2_5S;

    SoftTimer5Counter=ST_3S;

    SoftTimer6Counter=ST_3_5S;

    SoftTimer7Counter=ST_4S;

 

 

    while(1)

    {

        if(_testbit_(SoftTimer0Over))

        {

             SoftTimer0Counter=ST_0_5S;

             LED1=~LED1;

        }

        if(_testbit_(SoftTimer1Over))

        {

             SoftTimer1Counter=ST_1S;

             LED2=~LED2;

        }

        if(_testbit_(SoftTimer2Over))

        {

             SoftTimer2Counter=ST_1_5S;

             LED3=~LED3;

        }

        if(_testbit_(SoftTimer3Over))

        {

             SoftTimer3Counter=ST_2S;

             LED4=~LED4;

        }

        if(_testbit_(SoftTimer4Over))

        {

             SoftTimer4Counter=ST_2_5S;

             LED5=~LED5;

        }

        if(_testbit_(SoftTimer5Over))

        {

             SoftTimer5Counter=ST_3S;

             LED6=~LED6;

        }

        if(_testbit_(SoftTimer6Over))

        {

             SoftTimer6Counter=ST_3_5S;

             LED7=~LED7;

        }

        if(_testbit_(SoftTimer7Over))

        {

             SoftTimer7Counter=ST_4S;

             LED8=~LED8;

        }

    }

}

 

void TimerBaseByTimer0(void) interrupt 1

{

    if(SoftTimer0Counter)

    {

        SoftTimer0Counter–;

        if(!SoftTimer0Counter)

        {

            SoftTimer0Over=1;

        }

    }

 

    if(SoftTimer1Counter)

    {

        SoftTimer1Counter–;

        if(!SoftTimer1Counter)

        {

            SoftTimer1Over=1;

        }

    }

 

    if(SoftTimer2Counter)

    {

        SoftTimer2Counter–;

        if(!SoftTimer2Counter)

        {

            SoftTimer2Over=1;

        }

    }

 

    if(SoftTimer3Counter)

    {

        SoftTimer3Counter–;

        if(!SoftTimer3Counter)

        {

            SoftTimer3Over=1;

        }

    }

 

    if(SoftTimer4Counter)

    {

        SoftTimer4Counter–;

        if(!SoftTimer4Counter)

        {

            SoftTimer4Over=1;

        }

    }

 

    if(SoftTimer5Counter)

    {

        SoftTimer5Counter–;

        if(!SoftTimer5Counter)

        {

            SoftTimer5Over=1;

        }

    }

 

    if(SoftTimer6Counter)

    {

        SoftTimer6Counter–;

        if(!SoftTimer6Counter)

        {

            SoftTimer6Over=1;

        }

    }

 

    if(SoftTimer7Counter)

    {

        SoftTimer7Counter–;

        if(!SoftTimer7Counter)

        {

            SoftTimer7Over=1;

        }

    }

}

 

 

 

 

消息机制编程

生产消息,处理消息

#include
“stdio.h”

#include
“stdlib.h”

 

#define
MSG_TASK1_RUN 1

#define
MSG_TASK1_STOP 2

#define
MSG_TASK2_RUN 1

#define
MSG_TASK2_STOP 2

 

void main()

{

    unsigned
int RandTaskGene1;

    unsigned
char message1;

    unsigned
int RandTaskGene2;

    unsigned
char message2;

 

    while (1)

    {

        RandTaskGene1 = rand();    

        RandTaskGene1 %= 2;

        if (RandTaskGene1) //产生消息

        {

            message1 = MSG_TASK1_RUN;

        }

        else

        {

            message1 = MSG_TASK1_STOP;

        }

 

        RandTaskGene2 = rand();

        if (RandTaskGene2 > 1000)

        {

            message2 = MSG_TASK2_RUN;

        }

        else

        {

            message2 = MSG_TASK2_STOP;

        }

 

        if(message1)//检索消息

        {

            switch(message1)

            {

                case
MSG_TASK1_RUN:

                    printf(消息1事件1%d\n”, RandTaskGene1);

                    break;

                case
MSG_TASK1_STOP:

                    printf(消息1事件2%d\n”, RandTaskGene1);

                    break;

            }

        }

        if (message2)//检索消息

        {

            switch (message2)

            {

                case
MSG_TASK2_RUN:

                    printf(消息2事件1%d\n”, RandTaskGene2);

                    break;

                case
MSG_TASK2_STOP:

                    printf(消息2事件2%d\n”, RandTaskGene2);

                    break;

            }

        }

    }

}

消息进入队列处理

#include
“stdio.h”

#include
“stdlib.h”

 

typedef
unsigned
char
message;

 

//无消息

#define
MSG_NONE 0

 

#define
MSG_TASK1_RUN 1

#define
MSG_TASK1_STOP 2

#define
MSG_TASK2_RUN 3

#define
MSG_TASK2_STOP 4

 

/*消息处理机制定义*/

#define
QUEUELEN 5 //消息缓冲区大小

unsigned
char Messages[QUEUELEN]; //消息队列

unsigned
char MessageHead = 0; //消息队列头

unsigned
char MessageTail = 0; //消息列尾

//消息发布

void PutMessage(message
m)

{

    Messages[MessageTail] = m;

    if(++MessageTail>=QUEUELEN)

    {

        MessageTail = 0;

    }

}

//取消息

message GetMessage()

{

    message m = Messages[MessageHead];

    if (++MessageHead>=QUEUELEN)

    {

        MessageHead = 0;

    }

    return m;

}

//判断队列是否为空

bool QueueEmptyOrError()

{

    return (MessageHead == MessageTail) ? 1 : 0;

}

 

void main()

{

    unsigned
int RandTaskGene;

 

    while (1)

    {

        RandTaskGene = rand();    

        RandTaskGene %= 2;

        if (RandTaskGene) //产生消息

        {

            PutMessage( MSG_TASK1_RUN);

        }

        else

        {

            PutMessage( MSG_TASK1_STOP);

        }

 

        RandTaskGene = rand();

        if (RandTaskGene > 1000)

        {

            PutMessage( MSG_TASK2_RUN);

        }

        else

        {

            PutMessage(MSG_TASK2_STOP);

        }

 

        while(!QueueEmptyOrError())//一次性处理消息

        {

            switch (GetMessage())

            {

                case
MSG_TASK1_RUN:

                    printf(消息1事件1%d\n”, MSG_TASK1_RUN);

                    break;

                case
MSG_TASK1_STOP:

                    printf(消息1事件2%d\n”, MSG_TASK1_STOP);

                    break;

                case
MSG_TASK2_RUN:

                    printf(消息2事件1%d\n”, MSG_TASK2_RUN);

                    break;

                case
MSG_TASK2_STOP:

                    printf(消息2事件1%d\n”, MSG_TASK2_STOP);

                    break;

            }

        }

    }

}

 

 

 

动态数组

#include
“stdafx.h”

#include
“stdlib.h”

 

 

int main()

{

    int *p = NULL;

    

    p =(int*) malloc(10*sizeof(int));

    for (int i = 0; i < 10;i++)

    {

        p[i] = i;

    }

 

    for (int i = 0; i < 10; i++)

    {

        printf(“%d\n”,p[i]);

    }

 


return 0;

}

LCD1602液晶显示器

LCD1602引脚

引脚号

符号

引脚说明

引脚号

符号

引脚说明

1

VSS

电源地

9

D2

数据端口

2

VDD

电源正极

10

D3

数据端口

3

VO

偏压信号

11

D4

数据端口

4

RS

命令/数据

12

D5

数据端口

5

RW

读/写

13

D6

数据端口

6

E

使能,下降沿执行指令

14

D7

数据端口

7

D0

数据端口

15

A

背光正极

8

D1

数据端口

16

K

背光负极

 

基本操作

LCD1602的基本操作分为四种:

1.    读状态:输入RS=0,RW=1,E=高脉冲。输出:D0—D7为状态字。

2.    读数据:输入RS=1,RW=1,E=高脉冲。输出:D0—D7为数据。

3.    写命令:输入RS=0,RW=0,E=高脉冲。输出:无。

4.    写数据:输入RS=1,RW=0,E=高脉冲。输出:无。

读时序

写时序

 

DDRAM(Display Data RAM)就是显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下:

 

电路原理图

源代码

#include<reg51.h>

#include<string.h>

#include<intrins.h>

 

#define uchar unsigned char

#define uint unsigned int

 

sbit RS = P3^5;

sbit EN = P3^4;

sbit RW = P3^6;

uchar code table1[] = {“hello world!”};

uchar code table2[] = {“1991/02/03”};

 

void delay1ms(uint time);//延时N毫秒

void init_1602(void);     //初始化1602

void writecmd_1602(uint cmd);    //写指令函数

void writedata_1602(uchar dat);    //写数据函数

void display(uchar num,uchar * table);    //显示函数

 

int main()

{

    init_1602();            //初始化1602

    delay1ms(5);

    writecmd_1602(0x80);    //设置显示的起始位置

    delay1ms(5);

    display(strlen(table1),table1);

    writecmd_1602(0xC0);    //设置显示的起始位置

    delay1ms(5);

    display(strlen(table2),table2);

    while(1);

    return 0;

}    

void delay1ms(uint time)     

{

unsigned char a,b,i;

    for(i = time; i != 0;i–)

        for(b=199;b>0;b–)

            for(a=1;a>0;a–);

}

void init_1602(void)

{

    writecmd_1602(0x38);    //模式设置,8位数据,2行显示,5*8点阵字符

    writecmd_1602(0x0F);    //显示设置,显示开,光标显示,光标闪烁    

    writecmd_1602(0x06);    //显示模式,写入新数据后光标右移    

    writecmd_1602(0x01);    //清屏

}

 

void writecmd_1602(uint cmd)

{

    RS = 0;

    RW = 0;

    P1 = cmd;

    EN = 1;

    delay1ms(1);

    EN = 0;

}

 

void writedata_1602(uchar dat)

{

    RS = 1;

    RW = 0;

    P1 = dat;

    EN = 1;

    delay1ms(1);

    EN = 0;

}

void display(uchar num,uchar * table)

{

    uchar i;

    for(i = 0; i < num; i++)

    {

        writedata_1602(table[i]);

    }

    delay1ms(5);

}

 

 

自定义显示字符

写入CGRAM存储器的指令

共有64个存储区,每个8个存储区对应一个字符,所以可以自定义8个字符。如下图所示每个存储区的高3位不用。

显示自定义字符时,向DDRAM写入0x00至0x07即可,另外0x08至0x0F也能实现同样的功能。

#include<reg51.h>

 

#define uchar unsigned char

#define uint unsigned int

 

 

// 自定义字符 一共可写入16个自字义字符,写入后可用其CGRAM代码直接提取显示。

uchar code Xword[]={

0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, //℃,代码 0x00

0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00, //一,代码 0x01

0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00, //二,代码 0x02

0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00, //三,代码 0x03

0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00, //四,代码 0x04

0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00, //五,代码 0x05

0x00,0x04,0x00,0xff,0x00,0x0a,0x11,0x00, //六,代码 0x06

0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0xFF, //日,代码 0x07

};

 

sbit RS = P3^5;

sbit EN = P3^4;

sbit RW = P3^6;

 

void delay1ms(uint time);//延时N毫秒

void init_1602(void);     //初始化1602

void writecmd_1602(uint cmd);    //写指令函数

void writedata_1602(uchar dat);    //写数据函数

 

void CgramWrite(void) { // 装入CGRAM //

uchar i;

writecmd_1602(0x40); // CGRAM地址设为00处

for(i=0;i<64;i++)

    {

    writedata_1602(Xword[i]);// 按数组写入数据

}

}

 

int main()

{

    init_1602();            //初始化1602

    writecmd_1602(0xC0);    //设置显示的起始位置

    writedata_1602(0x00);

    writedata_1602(0x01);

    writedata_1602(0x02);

    writedata_1602(0x03);

    writedata_1602(0x04);

    writedata_1602(0x05);

    writedata_1602(0x06);

    writedata_1602(0x07);

    writedata_1602(0x20);

    while(1);

    return 0;

}    

 

void delay1ms(uint time)     

{

unsigned char a,b,i;

    for(i = time; i != 0;i–)

        for(b=199;b>0;b–)

            for(a=1;a>0;a–);

}

 

void init_1602(void)

{

    writecmd_1602(0x38);    //模式设置,8位数据,2行显示,5*8点阵字符

    writecmd_1602(0x0F);    //显示设置,显示开,光标显示,光标闪烁    

    writecmd_1602(0x06);    //显示模式,写入新数据后光标右移    

    writecmd_1602(0x01);    //清屏

    delay1ms(5);

    CgramWrite();

}

 

void writecmd_1602(uint cmd)

{

    RS = 0;

    RW = 0;

    P1 = cmd;

    EN = 1;

    delay1ms(1);

    EN = 0;

}

 

void writedata_1602(uchar dat)

{

    RS = 1;

    RW = 0;

    P1 = dat;

    EN = 1;

    delay1ms(1);

    EN = 0;

}

运行结果如下

 

 

2021年8月24日

C# 匿名方法和Lambda表达式

常规操作,我们要使用一个委托,需要有三个步骤:声明委托,定义委托变量,实例化委托。

using System;

 

namespace ConsoleApplication2

{


class
Program

{


delegate
int
delAdd(int a,int b);


static
void Main(string[] args)

{


delAdd add = new
delAdd(Add);


int c = add(123,456);


Console.WriteLine(c);

}

 


static
int Add(int a,int b)

{


return a + b;

}

}

}

如果上述程序中的Add函数,我们可能就用一次或者只关联到一个委托变量上,是不是没有必要专门定义一个函数呢?这样就出现了匿名方法。

using System;

 

namespace ConsoleApplication2

{


class
Program

{


delegate
int
delAdd(int a,int b);


static
void Main(string[] args)

{


delAdd add = delegate (int a, int b) { return a + b; };


int c = add(123,456);


Console.WriteLine(c);

}

}

}

也许微软觉得匿名方法表达还是比较啰嗦,出现了Lambda表达式。程序可以写成下面这个样子了。

using System;

 

namespace ConsoleApplication2

{


class
Program

{


delegate
int
delAdd(int a,int b);


static
void Main(string[] args)

{


delAdd add = (int a, int b) =>{ return a + b; };


int c = add(123,456);


Console.WriteLine(c);

}

}

}

委托和泛型结合起来,出现了泛型委托,微软定义了两个泛型委托,无返回值的Action和有返回值的Func

namespace ConsoleApplication2

{


class
Program

{


static
void Main(string[] args)

{


Func<int,int,int> add = (int a, int b) =>{ return a + b; };


int c = add(123,456);


Console.WriteLine(c);

}

}

}

异步实现await和Async

异步实现方式

async和await,例程如下

using System;

using System.Drawing;

using System.Windows.Forms;

using System.Net;

using System.Net.Http;

 

namespace WindowsFormsApplication4

{


public
partial
class
Form1 : Form

{


public Form1()

{

InitializeComponent();

}

 


private
async
void button1_Click(object sender, EventArgs e)

{


string imageUrl = @”http://www.dianqirensheng.com/wp-content/uploads/2021/09/091621_0200_1.png”;


HttpClient client = new
HttpClient();


HttpResponseMessage response = await client.GetAsync(imageUrl);


if(response.StatusCode==HttpStatusCode.OK)

{


var stream = await response.Content.ReadAsStreamAsync();


Image image = Bitmap.FromStream(stream, true);

pictureBox1.Image = image;

}

}

}

}

 

执行结果

 

异步实现的示例


private
async
void button2_Click(object sender, EventArgs e)

{


int d = await GetValueAsync(9);


MessageBox.Show(d.ToString());

}

 


private
static
async
Task<int> GetValueAsync(int a)

{


int c=0;


await
Task.Run(()=>

{


Thread.Sleep(10000);

c = a * a;

});


return c;

}

 

 

 

 

 

掩码

将源码与掩码经过按位运算或逻辑运算得出新的操作数。其中要用到按位运算如OR运算和AND运算。

用于如将ASCII码中大写字母改作小写字母。如A的ASCII码值为65= (01000001)2,a的ASCII码值为97=(01100001)2,要想把大写字母A转化为小写字母只需要将A的ASCII码与(00100000)2进行或运算就可以得到小写字母a。

最常用到的子网掩码

IP地址为192.168.10.2,子网掩码为255.255.255.240。

先将十进制转换成二进制:

IP地址: 11000000 10101000 00001010 00000010

子网掩码:11111111 11111111 11111111 11110000

进行与运算:--------------------------

11000000 10101000 00001010 00000000

则可得其网络标识为192.168.10.0,主机标识为2。

2021年9月22日

跨线程访问控件二

我第一次碰到跨线程访问可视化控件的问题是在写串口通讯程序的时候。

我不会再举出那个例子,有点麻烦。我们用下面这个例子,制造这个现象。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public Form1()

{

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


ThreadStart ts = new
ThreadStart(PrintLable);


Thread th = new
Thread(ts);

th.Start();

 

 

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

 

在.NET 2.0之前是允许跨线程访问可视化控件的,后续就不允许了,可能是基于界面跨线程访问容易造成混乱的原因吧。比如界面在刷新,突然插入个新的程序要更改界面的数据,容易造成混乱。

最简单的解决办法就是添加一条语句,加粗的那一句。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public Form1()

{


Control.CheckForIllegalCrossThreadCalls = false;

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


ThreadStart ts = new
ThreadStart(PrintLable);


Thread th = new
Thread(ts);

th.Start();

 

 

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

但是官方并不鼓励我们这么做,要不他们也不会费这么大劲了。

窗体是由UI线程创建的,这个UI线程拥有一个消息队列和相应的操作函数,负责接收操作系统发过来的各种消息并做处理,比如鼠标点击,键盘输入等等。

官方提供了相应的法案,把对可视化控件的访问转有UI线程负责。

Control.Invoke 同步方式

Control.BeginInvoke 异步方式

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public
delegate
void
MyInvoke();


public Form1()

{

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


MyInvoke myIvoke = new
MyInvoke(PrintLable);

label1.Invoke(myIvoke);

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

 

 

 

跨线程访问

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace test

{


public
partial
class
Form1 : Form

{


public Form1()

{

InitializeComponent();

}


static
int i;

 


private
void button1_Click(object sender, EventArgs e)

{


Thread th = new
Thread(new
ParameterizedThreadStart(showmsg) );

th.Start(“button1”);

}

 


void showmsg(Object s)

{


if(this.textBox1.InvokeRequired)

{


mydelegate d = show;


this.textBox1.Invoke(d,s);

}


else

{

show(s.ToString());

}

 

}

 


delegate
void
mydelegate(string s);


void show(string s)

{


this.textBox1.AppendText(s.ToString() + “\r\n”);


this.textBox1.AppendText(i.ToString() + “\r\n”);

i++;

}

 


private
void button2_Click(object sender, EventArgs e)

{

showmsg(“button2”);

}

}

}

跨线程访问控件二

我第一次碰到跨线程访问可视化控件的问题是在写串口通讯程序的时候。

我不会再举出那个例子,有点麻烦。我们用下面这个例子,制造这个现象。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public Form1()

{

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


ThreadStart ts = new
ThreadStart(PrintLable);


Thread th = new
Thread(ts);

th.Start();

 

 

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

 

在.NET 2.0之前是允许跨线程访问可视化控件的,后续就不允许了,可能是基于界面跨线程访问容易造成混乱的原因吧。比如界面在刷新,突然插入个新的程序要更改界面的数据,容易造成混乱。

最简单的解决办法就是添加一条语句,加粗的那一句。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public Form1()

{


Control.CheckForIllegalCrossThreadCalls = false;

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


ThreadStart ts = new
ThreadStart(PrintLable);


Thread th = new
Thread(ts);

th.Start();

 

 

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

但是官方并不鼓励我们这么做,要不他们也不会费这么大劲了。

窗体是由UI线程创建的,这个UI线程拥有一个消息队列和相应的操作函数,负责接收操作系统发过来的各种消息并做处理,比如鼠标点击,键盘输入等等。

官方提供了相应的法案,把对可视化控件的访问转有UI线程负责。

Control.Invoke 同步方式

Control.BeginInvoke 异步方式

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace WindowsFormsApplication6

{


public
partial
class
Form1 : Form

{


public
delegate
void
MyInvoke();


public Form1()

{

InitializeComponent();

}

 


private
void button1_Click(object sender, EventArgs e)

{


MyInvoke myIvoke = new
MyInvoke(PrintLable);

label1.Invoke(myIvoke);

}

 


private
void PrintLable()

{


this.label1.Text = 跨线程访问控件了!;

}

}

}

 

 

 

跨线程访问

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Threading;

 

namespace test

{


public
partial
class
Form1 : Form

{


public Form1()

{

InitializeComponent();

}


static
int i;

 


private
void button1_Click(object sender, EventArgs e)

{


Thread th = new
Thread(new
ParameterizedThreadStart(showmsg) );

th.Start(“button1”);

}

 


void showmsg(Object s)

{


if(this.textBox1.InvokeRequired)

{


mydelegate d = show;


this.textBox1.Invoke(d,s);

}


else

{

show(s.ToString());

}

 

}

 


delegate
void
mydelegate(string s);


void show(string s)

{


this.textBox1.AppendText(s.ToString() + “\r\n”);


this.textBox1.AppendText(i.ToString() + “\r\n”);

i++;

}

 


private
void button2_Click(object sender, EventArgs e)

{

showmsg(“button2”);

}

}

}