begininvoke(begininvoke 无响应)

http://www.itjxue.com  2023-01-24 19:50  来源:未知  点击次数: 

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的上下文中执行。

(责任编辑:IT教学网)

更多

相关广告特效文章

推荐广告特效文章