C#多线程问题

第一次在winform写多线程代码遇到很多问题:

1.方法委托创建多线程后该方法就会往下执行,控制子线程执行完主线程再继续往下执行用到两种方法:可获取工作线程==最大工作线程时表示子线程都执行完成;使用信号量控制(曾经学操作系统时不知道有什么用)现在发现多线程通信过程信号量还是很重要的。

2.winform控件默认不允许非创建控件线程操作控件,只有多线程编程才会出现这个跨线程通信问题。解决办法有两种:使用委托来委托主线程帮忙调用相关操作;设置CheckForIllegalCrossThreadCalls = false但是这个设置是线程不安全的,多线程执行过过程中对控件操作需要加锁否则会出现不一致信,亲测不加锁过程控件会为空发生空对象调用错误。

3.多线程控制函数执行间同步和异步和异步的关系,使用BeginInvoke和EndInvoke。

在调用BeginInvoke可以做以下工作:

  1. 做一些其他操作,然后调用EndInvoke方法阻塞线程直到该方法完成。
  2. 使用IAsyncResult.AsyncWaitHandle属性,使用它的WaitOne方法阻塞线程直到收到WaitHandle信号,然后调用EndInvoke。
  3. 检查BeginInvoke返回值IAsyncResult的状态来决定方法是否完成,然后调用EndInvoke方法。
  4. 通过在BeginInvoke方法中传递该委托,在回调方法中调用该委托的EenInvoke方法。

4.了解了lock、信号量、加锁和Interlocked原子操作都是不同类别的操作。

  1. lock是锁定代码块,每个时刻最多只有一个线程中lock代码块在执行。lock可以逻辑上实现加排它锁,只需要在加锁的变量每次使用前加lock就可以实现排它锁的逻辑效果,它不是一种原子操作,即在该代码块执行过程中可能会被阻塞。
  2. 锁有两种类型:分别为排它锁和共享锁,它们也不是一种原子操作只是控制数据访问时数据一致性的问题。
  3. 信号量是控制很多资源的分配与回收时的排他性,它也是一种锁但是不像排它锁和共享锁那样控制一个数据的简单访问,而是控制很多数据或者代码块的资源访问问题。
  4. lock和信号量间的代码块只是控制数据访问冲突的问题,原子操作是控制一种或多种操作集合要么一次性都做要么都不做问题,即lock和信号量间代码块可能执行到一半会被阻塞,但是原子操作总的代码块不会被阻塞。

5.子线程委托主线程执行相关代码时,但是主线程在waitone阻塞等待子线程执行完成,这就出现了一个死锁问题,因为主线程在阻塞等待子线程执行完,而子线程委托主线程执行相关代码后才能执行完就出现了死锁。这时候就要使用到CheckForIllegalCrossThreadCalls = false同时还要对空间加上排它锁的功能。

6.多线程中数据的写操作一定要万分小心谨慎思考要不要加排它锁,一旦不注意。可能要运行很长时间才会出问题,同时debug时非常浪费时间。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页