在上述代码中有这样一条奇怪语句
CheckForIllegalCrossThreadCalls = false;//允许跨线程调用
在.net上执行的是托管代码,C#强制要求这些代码必须是线程安全的,不允许跨线程访问windows窗体控件。儿这条语句是将C#内置控件(Control)类的CheckForIllegalCrossThreadCalls属性为false,以屏蔽C#编译器对跨线程调用的检查。这种做法是不安全的。如何在遵守.net安全标准前提下从一个线程访问另一个线程创建的控件,就要使用到C#回调机制。
定义、声明回调
private delegate void WriTextBox1Callback(char ch);
private WriTextBox1Callback wriTextBox1Callback;//“回调”WriTextBox1Callback其实就是一个委托
初始化回调方法
wriTextBox1Callback = new WriTextBox1Callback(WriText1);//其实就是实例化委托,这里的WriText1称为“回调方法”
触发对象动作
textBox1.Invoke(wriTextBox1Callback,ch);//将委托wriTextBox1Callback作为参数传递给控件的Invoke方法
采用回调、线程和委托机制实现“文字抄写员”
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 ThreadCallback
{
public partial class Form1 : Form
{
//声明委托以实现回调机制
private delegate void WriteTextBox(char ch);//自定义委托
private WriteTextBox writeTextBox;
//操作文本1的回调
private delegate void WriTextBox1Callback(char ch);
private WriTextBox1Callback wriTextBox1Callback;
//操作文本2的回调
private delegate void WriTextBox2Callback(char ch);
private WriTextBox2Callback wriTextBox2Callback;
public Form1()
{
InitializeComponent();
//CheckForIllegalCrossThreadCalls = false;//允许跨线程调用
wriTextBox1Callback = new WriTextBox1Callback(WriText1);
wriTextBox2Callback = new WriTextBox2Callback(WriText2);
}
private void button1_Click(object sender, EventArgs e)
{
if (checkBox1.Checked == true)
{
textBox1.Clear();
textBox1.Refresh();
ThreadStart doTask1 = new ThreadStart(DoTask1);
Thread tsk1Thread = new Thread(doTask1);
tsk1Thread.Start();
}
if (checkBox2.Checked == true)
{
textBox2.Clear();
textBox2.Refresh();
ThreadStart doTask2 = new ThreadStart(DoTask2);
Thread tsk2Thread = new Thread(doTask2);
tsk2Thread.Start();
}
}
private void DoTask1()
{
//使用回调
writeTextBox = new WriteTextBox(WriTextBox1);
WriText(writeTextBox);
}
private void DoTask2()
{
//使用回调
writeTextBox = new WriteTextBox(WriTextBox2);
WriText(writeTextBox);
}
private void WriText(WriteTextBox wMethod)
{
string str = textBox3.Text;
for (int i = 0; i < str.Length; i++)
{
wMethod(str[i]);
//延时
DateTime now = DateTime.Now;
while (now.AddSeconds(1)>DateTime.Now){}
}
}
private void WriTextBox1(char ch)
{
//使用回调语句
textBox1.Invoke(wriTextBox1Callback,ch);
}
private void WriTextBox2(char ch)
{
//使用回调语句
textBox2.Invoke(wriTextBox2Callback, ch);
}
private void WriText1(char ch)
{
textBox1.AppendText(ch + "\r");
}
private void WriText2(char ch)
{
textBox2.AppendText(ch +"\r");
}
}
}