同步与异步区别,Invoke与BeginInoke的区别与一点理解
2011-12-06 09:58
106 查看
先说同步与异步的区别,总说同步异步的,其实一直不清楚什么是同步异步,今天找了一下:
同步:当一个消息发送后,等对方回应后继续发送下一条指令。
异步:当一个消息发送后,不等对方回应就发送下一条。
异步:刚才被更正了,异步是,接收方不进行处理立即返回。
同步,举个例子,就是你给人打电话的时候,你说一句,对方回你一句,然后你在说下一句,交流嘛。
异步呢,你给一个人打电话,你一直在说。
而BeginInvoke与Invoke就是同步与异步。BeginInvoke是异步操作,Invoke是同步操作。而这两个方法中执行的是一个委托。
举一个代码中的例子,在WPF中有一个TextBlock控件,Name属性为txtContent有时候会出现跨线程的问题,这个什么时候出现,我现在不知道为啥模拟不出来了。但是我记得这样的写法,因为我感觉这样的写法就是为了防止出现这种问题的。是这样写的:
如果带有参数的话就这么写:
如果多个参数的话,Action泛型中增加就可以了。后面也相对的增加传递的值。
使用Dispatcher.Invoke就是所谓的同步更新,异步更新呢?就是吧Invoke换为BeginInvoke就是异步了,其实看了一些资料我还是没明白Invoke和BeginInvoke到底有什么区别。但是呢,更新界面的话,必须是UI线程,也就是谁创建了UI控件就由谁来更新,跨线程更新是肯定会报错的。所以,也就有了BeginInvoke和Invoke的方法了,使用这种方法调用的也就不报错了,因为这两个还是运行在UI线程上的。
找这个理解的话,写在BeginInvoke中的委托更新要比Invoke好,因为Invoke是同步更新,要等任务结束后才会更新界面,BeginInvoke的话就不管了,异步嘛,不等,直接更新了。
昨天没写完,继续说。
但是上面的委托体内如果有耗时操作,还是会出现UI界面假死的状况,例如如下的代码:
如何才能更好的解决这种假死的情况呢?因为BeginInvoke和Invoke只是为了解决线程安全的问题,要解决假死的问题很多时候用到的都是BackgroupWorker。不多说了,但是我在网上查找资料的时候又找到了另外一种写法:
这种写法与BackgroupWorker有什么区别呢,不清楚,毕竟我不是高手,在这条路上探索的一个程序员而已。只是我觉得,不用写那么多行了。
更多内容请访问:http://luacloud.com/2011/begininvkod-and-invoke.html
同步:当一个消息发送后,等对方回应后继续发送下一条指令。
异步:当一个消息发送后,不等对方回应就发送下一条。
异步:刚才被更正了,异步是,接收方不进行处理立即返回。
同步,举个例子,就是你给人打电话的时候,你说一句,对方回你一句,然后你在说下一句,交流嘛。
异步呢,你给一个人打电话,你一直在说。
而BeginInvoke与Invoke就是同步与异步。BeginInvoke是异步操作,Invoke是同步操作。而这两个方法中执行的是一个委托。
举一个代码中的例子,在WPF中有一个TextBlock控件,Name属性为txtContent有时候会出现跨线程的问题,这个什么时候出现,我现在不知道为啥模拟不出来了。但是我记得这样的写法,因为我感觉这样的写法就是为了防止出现这种问题的。是这样写的:
txtContent.Dispatcher.Invoke(new Action(() => { txtContent.Text = "xxxxxxx"; }));
如果带有参数的话就这么写:
txtContent.Dispatcher.Invoke(new Action<string, string>((arg1, arg2) => { txtContent.Text = arg1 + arg2; }), "参数1", "参数2");
如果多个参数的话,Action泛型中增加就可以了。后面也相对的增加传递的值。
使用Dispatcher.Invoke就是所谓的同步更新,异步更新呢?就是吧Invoke换为BeginInvoke就是异步了,其实看了一些资料我还是没明白Invoke和BeginInvoke到底有什么区别。但是呢,更新界面的话,必须是UI线程,也就是谁创建了UI控件就由谁来更新,跨线程更新是肯定会报错的。所以,也就有了BeginInvoke和Invoke的方法了,使用这种方法调用的也就不报错了,因为这两个还是运行在UI线程上的。
txtContent.Dispatcher.BeginInvoke(new Action<string, string>((arg1, arg2) => { //此处写需要进行异步的操作 txtContent.Text = arg1 + arg2; }), "参数1", "参数2"); //或这样写 Dispatcher.BeginInvoke(new Action<TextBlock>((arg_txt) => { //此处写需要进行异步的操作 arg_txt.Text = "异步更新"; }), txtContent);
找这个理解的话,写在BeginInvoke中的委托更新要比Invoke好,因为Invoke是同步更新,要等任务结束后才会更新界面,BeginInvoke的话就不管了,异步嘛,不等,直接更新了。
昨天没写完,继续说。
但是上面的委托体内如果有耗时操作,还是会出现UI界面假死的状况,例如如下的代码:
txtContent.Dispatcher.BeginInvoke(new Action<string, string>((arg1, arg2) => { //此处写需要进行异步的操作 for (long i = 0; i < 2147483647; i++) txtContent.Text = arg1 + arg2 + i; }), "参数1", "参数2");
如何才能更好的解决这种假死的情况呢?因为BeginInvoke和Invoke只是为了解决线程安全的问题,要解决假死的问题很多时候用到的都是BackgroupWorker。不多说了,但是我在网上查找资料的时候又找到了另外一种写法:
Action ut = new Action(() => { //耗时操作 for (long i = 0; i < Int16.MaxValue; i++) txtContent.Dispatcher.Invoke(new Action(() => { txtContent.Text = string.Format("{0}", i); })); }); IAsyncResult result = ut.BeginInvoke(new AsyncCallback(new Action<IAsyncResult>((asyncResult) => { //耗时结束后的操作 if (asyncResult == null) return; ut.EndInvoke(asyncResult); })), ut);
这种写法与BackgroupWorker有什么区别呢,不清楚,毕竟我不是高手,在这条路上探索的一个程序员而已。只是我觉得,不用写那么多行了。
更多内容请访问:http://luacloud.com/2011/begininvkod-and-invoke.html
相关文章推荐
- 同步与异步区别,Invoke与BeginInoke的区别
- 同步与异步区别,Invoke与BeginInoke的区别
- 怎样理解阻塞非阻塞与同步异步的区别?
- 理解串行并行、同步异步与invoke、begininvoke和endinvoke的关系
- 怎样理解阻塞非阻塞与同步异步的区别?
- 怎样理解阻塞非阻塞与同步异步的区别
- 深入理解AJAX系列第三篇--async属性值之同步和异步及同步和异步区别
- 怎样理解阻塞非阻塞与同步异步的区别?
- 理解阻塞非阻塞与同步异步的区别
- 怎样理解阻塞非阻塞与同步异步的区别
- 理解阻塞/非阻塞、同步/异步的区别
- 理解 I/O-- 阻塞、非阻塞,同步、异步的概念及其区别
- 怎样理解阻塞非阻塞与同步异步的区别?
- 怎样理解阻塞非阻塞与同步异步的区别?
- 怎样理解阻塞非阻塞与同步异步的区别?
- 怎样理解阻塞非阻塞与同步异步的区别?
- 理解阻塞非阻塞与同步异步的区别
- 怎样理解阻塞非阻塞与同步异步的区别?(个人理解)
- 怎样理解阻塞非阻塞与同步异步的区别?
- 怎样理解同步异步与阻塞非阻塞的区别?