invoke java C#中Invoke的用法()

invoke java C#中Invoke的用法()

和 区别

一直对和的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解。

首先说下,和的使用有两种情况:

1. 中的、。

2. 中的、。

这两种情况是不同的,我们这里要讲的是第1种。下面我们在来说下.NET中对和的官方定义。

.(参数)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。

.(参数)方法:在创建控件的基础句柄所在线程上异步执行指定委托。

根据这两个概念我们大致理解表是同步、表示异步。

如果你的后台线程在更新一个UI控件的状态后不需要等待,而是要继续往下处理,那么你就应该使用来进行异步处理。

如果你的后台线程需要操作UI控件,并且需要等到该操作执行完毕才能继续执行,那么你就应该使用。

我们来做一个测试。

例子:

private void button1_Click(object sender, EventArgs e)
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
            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 invokeDelegate(invokeMethod));  
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
 private void invokeMethod()
{
            //Thread.Sleep(3000);
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");
} 

结论:我们运行后,看下程序的运行顺序,1AAA->3CCC和1BBB->1EEE ->3DDD 。

解释:主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过来将方法提交给主线程,然后子线 程等待主线程执行,直到主线程将方法执行完成(期间必须等待主线程的任务执行完成,才会去执行提交的任务)invoke java C#中Invoke的用法(),最后执 行子线程3DDD。

例子:

private void button1_Click(object sender, EventArgs e)
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
            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 invokeDelegate(invokeMethod));  
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}
 private void beginInvokeMethod()
        {
            //Thread.Sleep(3000);
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEEEEEEEEEEE");
        }

结论: 我们运行后看看执行的结果:1AAA->1BBB和3CCC->1EEE和3DDD。

解释: 主线程运行1AAA,然后1BBB和子线程3CCC同时执行invoke java,然后通过来将方法提交给主线程,然后主线程执行1EEE(主线程自己的任务执行完成), 同时子线程继续执行3DDD。

通过这个两段代码的测试比较,我们会发现其实和所提交的委托方法都是在主线程中执行的,其实根据我 和的定义我们要在子线程中来看这个问题,在例子中我们会发现所提交的委托方法执行完成后,才能继续执行 DDD;在例子中我们会发现所提交的委托方法后,子线程讲继续执行DDD,不需要等待委托方法的完成。 那么现在我们在回想下(同步)和(异步)的概念,其实它们所说的意思是相对于子线程而言的,其实对于控件的调用总是由 主线程来执行的。我们很多人搞不清这个同步和异步,主要还是因为我们把参照物选错了。其实有时候光看概念是很容易理解错误的。

解决从不是创建控件的线程访问它

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

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

而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI线程负担的目的了。

举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个..

using .;

//启动一个线程

=new (());

.Start();

//线程方法

void ()

this..Text=”我是一个文本框”;

如果你像上面操作,在或2008里是会有异常的…

正确的做法是用

using .;

test

class Form1 : Form

void ( str1, str2);

Form1()

();

void ()

mi = new ();

this.(mi, new {“我是文本框”,”haha”});

void ( , parm2)

this..Text = +parm2;

void ( , e)

= new (new ());

.Start();

注意代理的使用!

后面再次补充

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

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

其次,通过的方法来解决。

普通的委托方法例如:

delegate void SafeSetText(string strMsg);
private void SetText(string strMsg)
{
 if(textbox1.InvokeRequired)
 {
            SafeSetText objSet=new SafeSetText(SetText);
            textbox1.Invoke(objSet,new object[]{strMsg});
 }
 else
 {
   textbox1.Text=strMsg;
 }
}

在线程内需要设置的值时调用方法既可。我们还可以采用另一种委托的方式来实现,那就是匿名代理,例如:

delegate void SafeSetText(string strMsg);
private void SetText2(string strMsg)
{
  SafeSetText objSet = delegate(string str)
   {
       textBox1.Text = str;
   }
   textBox1.Invoke(objSet,new object[]{strMsg});
}

这样同样可以实现。

个人觉得还是采用代理好些。

在C# 3.0及以后的版本中有了Lamda表达式invoke java,像上面这种匿名委托有了更简洁的写法。.NET  3.5及以后版本更能用封装方法。例如以下写法可以看上去非常简洁:

void ( , e)

this.(new (()=>

.Text=”关闭”;

}));

最新:

(() =>

.Text=”关闭”;

});

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » invoke java C#中Invoke的用法()

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们