Chinaunix首页 | 论坛 | 博客
  • 博客访问: 214554
  • 博文数量: 43
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-11 11:49
文章分类

全部博文(43)

文章存档

2009年(39)

2008年(4)

我的朋友

分类: C/C++

2009-04-20 17:42:51

点击下载此文件1.1,问题的引入

      Mobile资源有限,这都是大家所共知的,当我们使用Mobile访问远程Web服务的时候,如果返回数据量很大,或者出现网络不好的情况,就会出现,界面卡壳的情况。当然,作为开发人员,我相信,我们会做得更好,使用异步调用。

 


 

 

2.1,多种异步方式

      我们都知道异步实现,一般就两种方式,另辟线程和异步委托(其实异步委托就是另辟线程,只是系统在幕后,帮我们做了这些事情,至于为什么?下面会讲到)

2.1.1,另辟线程方式
 

图1.1
 

public void DoThreading()
        
{
            
// 创建并启动辅助线程
            ThreadStart starter = new ThreadStart(this.UpdateListBox);
            Thread t 
= new Thread(starter);
            t.Start();

            
// 循环 4 次,每次都向 ListBox 中添加一条消息
            for(int i = 0; i < 4; i++)
            
{
            
this.listBox1.Items.Add("来自 UI 线程的消息");
            
this.listBox1.Update();

            
//// 处理 UI 线程中排队的事件
            //Application.DoEvents();
            //// 将进程挂起一秒钟
            //Thread.Sleep(1000);

            }

            
this.listBox1.Items.Add("来自 UI 线程的上一条消息");
            
this.listBox1.Update();
        }


        
public void UpdateListBox()
        
{
            
for(int j = 0; j < 5; j++)
            
{
            
// 设置要从辅助线程添加到 ListBox 中的
            
// 消息
            this.Message = "辅助线程的循环数 = " + j.ToString();
            
// 在 ListBox 的线程上下文中调用 WorkerUpdate
            
// 方法
            this.listBox1.Invoke(new EventHandler(WorkerUpdate));
            
//Thread.Sleep(700);
            }

        }

        
// 为更新 ListBox 从辅助线程中
        
// 调用的代理
        public void WorkerUpdate(object sender, EventArgs e)
        
{
            
this.listBox1.Items.Add(this.Message);
            
this.listBox1.Update();
        }


 

图1.1中,通过开辟多线程,使用他的回调方法来异步更新界面。
 

2.1.2,异步委托方式
 

图1.2

private void button1_Click(object sender, EventArgs e)
        
{
            
            
// 创建 XML Web Service 代理类的实例
            TestWebService.Service  ws = new TestWebService.Service();
            ws.Url 
= "";
            
// 创建对回调委托的引用
            AsyncCallback cb = new AsyncCallback(ServiceCallback);
            
// 调用 Begin 方法,将回调委托和
            
// 此代理类实例作为 AsyncState 对象传递。
                ws.BeginHelloWorld(Convert.ToInt32(this.textBox1.Text),cb,ws);
            }


            
private void ServiceCallback(IAsyncResult ar)
            
{
                
// 将 AsyncState 对象转换为代理对象
                TestWebService.Service ws = (TestWebService.Service)ar.AsyncState;
                
                
//this.textBox1.Text= ws.EndHelloWorld(ar);
                this.msg= ws.EndHelloWorld(ar);
                
if (textBox1.InvokeRequired)
                    
this.textBox1.Invoke(new EventHandler(WorkerUpdate));
                
else
                
{
                    
this.textBox1.Text = this.msg;
                    
this.textBox1.Update();
                }

            
            }


        
public void WorkerUpdate(object sender, EventArgs e)
        
{
            
this.textBox1.Text=this.msg;
            
this.textBox1.Update();
        }

 

图1.2中,通过构造一个异步委托对象来传递我们的消息。

3.1,共同之处

      虽然处理方式不同,当消息都是从UI线程之外的线程中获取的,然后通过Control的Invoke方法来实现跨线程间的通信。其实我们看看这句话this.textBox1.Invoke(new EventHandler(WorkerUpdate)),很明显,是通过在UI线程上挂一个委托,来实现消息传递的。


 

4.1,范例代码 点击下载

 

点击下载此文件1
 http://www.cnblogs.com/wmj/archive/2008/12/18/1357540.html

阅读(596) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~