Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Yuzhiy05/Yuzhiy05.github.io
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuzhiy05 committed Jan 2, 2025
2 parents d62ac59 + f952fde commit 705758e
Showing 1 changed file with 87 additions and 1 deletion.
88 changes: 87 additions & 1 deletion docs/c#/c#随记.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,90 @@ public static bool Yield ();
[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public void Start ();
```
启动线程
启动线程

控件的Invoke方法
在主线程间开子线程,如果子线程需要修改主线程的空间则需要Invoke方法.不然线程间资源无法跨线程访问。同时Invoke会把委托交给主线程运行。阻塞当前子线程。当主线程执行完成后返回子线程所谓"同步"

Invoke
```c#
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
var invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}
private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.Invoke(new Action(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}

private void invokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");
}
```

和begininvoke的区别

```c#
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
var invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
string a = string.Empty;
for (int i = 0; i < 3; i++) //调整循环次数,看的会更清楚
{
Thread.Sleep(1000);
a = a + "B";
}
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}

private void StartMethod()
{
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
button1.BeginInvoke(new Action(invokeMethod));
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}

private void beginInvokeMethod()
{
//Thread.Sleep(3000);
MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEEEEEEEEEEE");
}
```

将方法委托给主线程后,子线程可继续执行DDD而不需要等待主线程返回。

在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。

正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会

在 WinForm开发过程中经常会用到线程,有时候还往往需要在线程中访问线程外的控件,比如:设置textbox的Text属性等等。如果直接设置程序必 定会报出:从不是创建控件的线程访问它,这个异常。通常我们可以采用两种方法来解决。一是通过设置control的属性。二是通过delegate,而通 过delegate也有两种方式,一种是常用的方式,另一种就是匿名方式。下面分别加以说明.


首先,通过设置control的一个属性值为false.我们可以在Form_Load方法中添加:Control.CheckForIllegalCrossThreadCalls=false;来解决。设置为false表示不对错误线程的调用进行捕获。这样在线程中对textbox的Text属性进行设置时就不会再报错了。

Invoke(Action)
在拥有控件的基础窗口句柄的线程上执行指定的委托。

Invoke(Delegate)
在拥有控件的基础窗口句柄的线程上执行指定的委托。

Invoke(Delegate, Object[])
在拥有控件的基础窗口句柄的线程上,使用指定的参数列表执行指定的委托。

Invoke<T>(Func<T>)
在拥有控件的基础窗口句柄的线程上执行指定的委托。

0 comments on commit 705758e

Please sign in to comment.