namespace XXX
{
public partial class Form1 : Form
{
public Form1()
{
//CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
}
private SynchronizationContext winfomsyncContext= WindowsFormsSynchronizationContext.Current;
private void Form1_Load(object sender, EventArgs e)
{
//方法1.取消跨线程访问空间检查:CheckForIllegalCrossThreadCalls = false;
//这个方法不好,掩耳盗铃~~~
}
private void button1_Click(object sender, EventArgs e)
{
//推荐用InvokeRequired,Invoke
Thread th = new Thread(MM)
{
IsBackground = true,
Priority = ThreadPriority.Highest
};
th.Start();
//多线程用Task,语句更简单
//Task.Run(() => MM());
}
static readonly object obj = new object();
void MM()
{
Stopwatch st = new Stopwatch();
st.Start();
//多个线程同时访问一个方法时 需要锁定,注意obj对象不能定义在方法内部,
//因为这样不同的多线程执行方法时obj对象都不同,所以要定义在方法外.
lock (obj)
{
for (int i = 0; i < 1001; i++)
{
Thread.Sleep(2);
if (textBox1.InvokeRequired)//不同线程访问了该控件
{
//实例化Action对象,一般是直接赋值方法名Action对象
//Action<TextBox, string> action = SetTextBoxValue;
//action(textBox1, "123");
//可以这么写:将方法作为参数传递给Action对象,
//Action<TextBox, string> myAction = new Action<TextBox, string>(SetTextBoxValue);
//myAction(textBox1, "w45345");
//Invoke方法重载,第一个参数是action引用的方法,第二个第三个参数是调用方法用到的参数,顺序和方法定义的参数顺序相同
//public object Invoke(Delegate method);
//public object Invoke(Delegate method, params object[] args);
textBox1.Invoke(new Action<TextBox, string>(SetTextBoxValue), textBox1, i.ToString());//跨线程赋值
}
else
{
textBox1.Text = i.ToString();//UI线程赋值,即同线程赋值
}
}
}
st.Stop();
double du = st.ElapsedMilliseconds;
}
void SetTextBoxValue(TextBox txtbox,string info)
{
txtbox.Text = info;
}
}
}