begininvoke(begininvoke 无响应)
c#中invoke和begininvoke的区别
区别在于Invoke是同步,BeginInvoke是异步。
打个比方(伪代码),后台线程中需要通知UI界面进行刷新
new?Thread()
{
???/*?比如读取数据库的方法,比较耗时;
???var?data?=?GetData();?读取完成后通知UI线程,
???this.Invoke(data);??//如果GetData方法是同步方法,则用Invoke回调
??//this.BeginInvoke(data);?//如果GetData是异步方法,则用BeginInvoke回掉???
}
在.NET?4.5或者更早的版本中,如果异步方法使用Invoke也是可以编译通过的,同时在Debug的时候也不会有问题,但是发布出去就会出异常。同步方法用BeginInvoke也是如此。
之前项目中出现过一次异步方法用Invoke回调,总是出异常,而且vs调试了很久都不知道问题出在哪里,?所以一定要弄清楚后台运行的方式到底是同步还是异步。
c#中invoke 和 begininvoke 都什么时候用
这两个方法最常用的场合是:多线程环境下更新控件。
例如,在WinForm程序中有一个后线程不断生成新的数字,而程序需要将这个数字在label1控件上显示,这是就需要调用Label控件的nvoke或者BeginInvok方法。
using?System;
using?System.Drawing;
using?System.Windows.Forms;
namespace?WindowsFormsApplication1
{
????public?partial?class?Form1?:?Form
????{
????????//?委托
????????delegate?void?MyDelegate(int?x);
????????public?Form1()
????????{
????????????InitializeComponent();
????????????//?启动一个后台线程
????????????System.Threading.Thread?t?=?
????????????????new?System.Threading.Thread(MyThread);
????????????t.IsBackground?=?true;
????????????t.Start();
????????}
????????void?MyMethod(int?x)
????????{
????????????label1.Text?=?x.ToString();
????????}
????????void?MyThread()
????????{
????????????int?x?=?0;
????????????//?实例化委托
????????????MyDelegate?md?=?MyMethod;
????????????
????????????//?线程循环
????????????while?(true)
????????????{
????????????????x++;
????????????????
????????????????//?利用Invok,调用委托?md,?在label1上显示x的值
????????????????label1.Invoke(?md,?x);
????????????????
????????????????//??也可以调用BeginInvok
????????????????//?label1.BeginInvoke(md,?x);
????????????????
????????????????//?休眠1秒钟
????????????????System.Threading.Thread.Sleep(1000);
????????????}
????????}
????}
}

C#中Invoke 和 BeginInvoke 的区别
区别在于Invoke是同步,BeginInvoke是异步。
打个比方(伪代码),后台线程中需要通知UI界面进行刷新
new?Thread()
{
???/*?比如读取数据库的方法,比较耗时;
???var?data?=?GetData();?读取完成后通知UI线程,
???this.Invoke(data);??//如果GetData方法是同步方法,则用Invoke回调
??//this.BeginInvoke(data);?//如果GetData是异步方法,则用BeginInvoke回掉???
}
在.NET?4.5或者更早的版本中,如果异步方法使用Invoke也是可以编译通过的,同时在Debug的时候也不会有问题,但是发布出去就会出异常。同步方法用BeginInvoke也是如此。
之前项目中出现过一次异步方法用Invoke回调,总是出异常,而且vs调试了很久都不知道问题出在哪里,?所以一定要弄清楚后台运行的方式到底是同步还是异步。
C#为什么要使用Invoke,它和BeginInvoke有什么区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate。
一、为什么Control类提供了Invoke和BeginInvoke机制?
关于这个问题的最主要的原因已经是dotnet程序员众所周知的,我在此费点笔墨再次记录到自己的日志,以便日后提醒一下自己。
1、windows程序消息机制
Windows GUI程序是基于消息机制的,有个主线程维护着一个消息泵。这个消息泵让windows程序生生不息。
Windows GUI程序的消息循环
Windows程序有个消息队列,窗体上的所有消息是这个队列里面消息的最主要来源。这里的while循环使用了GetMessage()这个方法,这是个阻塞方法,也就是队列为空时方法就会被阻塞,从而这个while循环停止运动,这避免了一个程序把cpu无缘无故地耗尽,让其它程序难以得到响应。当然在某些需要cpu最大限度运动的程序里面就可以使用另外的方法,例如某些3d游戏或者及时战略游戏中,一般会使用PeekMessage()这个方法,它不会被windows阻塞,从而保证整个游戏的流畅和比较高的帧速。
这个主线程维护着整个窗体以及上面的子控件。当它得到一个消息,就会调用DispatchMessage方法派遣消息,这会引起对窗体上的窗口过程的调用。窗口过程里面当然是程序员提供的窗体数据更新代码和其它代码。
2、dotnet里面的消息循环
public static void Main(string[] args)
{
Form f = new Form();
Application.Run(f);
}
Dotnet窗体程序封装了上述的while循环,这个循环就是通过Application.Run方法启动的。
3、线程外操作GUI控件的问题
如果从另外一个线程操作windows窗体上的控件,就会和主线程产生竞争,造成不可预料的
子线程中调用this.begininvoke会不会阻塞主线程
子线程中调用this.begininvoke不会阻塞主线程的。
这个很简单,在主程序里把那个子函数变成一个线程就可以了。这样那个子函数线程会等a任务线程完成后自己结束的。
假设你原来的程序是这样的:
void main()
{
func();
}
void func()
{
...
pthread_create(thr,NULL,aFunc,NULL);
pthread_join(thr,NULL);
}
那么现在把子函数变成线程:
void main()
{
...
pthread_t thr;
pthread_create(thr,NULL,(void
Invoke和BeginInvoke的区别
查看MSDN如下:
Control..::.Invoke --- 在拥有此控件的基础窗口句柄的线程上执行委托。
Control..::.BeginInvoke --- 在创建控件的基础句柄所在线程上异步执行委托。
显然,Invoke() 与 BeginInvoke() 方法间的主要区别在于“异步”关键字眼。
也就是说,
Invoke() 调用时,会阻塞当前线程,等到 Invoke() 方法返回才继续执行后面的代码,表现出“同步”的概念。
BeginInvoke() 调用时,当前线程会启用线程池中的某个线程来执行此方法,当前线程不被阻塞,继续运行后面的代码,表现出“异步”的概念。
EndInvoke() ,在想获取 BeginInvoke() 执行完毕后的结果时,调用此方法来获取。
控件为何会需要Invoke()或BeginInvoke()方法呢?
因为控件的这样一个特点:控件的数据(或状态)值只能在创建控件的那个线程上被更改。也就是说如果控件是在线程A上创建的,则其它任何线程B都不允许修改控件的值,只可以访问(读取)。控件的值只能在线程A上进行更改。
基于以上原因,而又有这样的需求:控件在线程A上创建,又要在线程B中更改其值。所以,Invoke()/BeginInvoke() 就出现了。使线程B可以间接地更改在线程A中创建的控件的值。真正更改控件值的操作仍然是在线程A的上下文中执行。