Dragon in the sky

whatever happened , go ahead! Happy life of big pig and its dog.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

委托应用场景[摘]

Posted on 2009-12-15 10:56  龙泰  阅读(1448)  评论(0编辑  收藏  举报

委托除了实现事件外,还能够实现很多非常有用的语言特性。
1、Lambda 表达式。Lambda 表达式有两种存在方式,一是匿名委托,而是表达式树。
2、匿名方法。不指定名称的委托成为匿名委托。有时候非常有用,如在绑定事件处理程序或者创建线程时。
3、多线程同步以及跨线程操作。
4、泛型委托。
5、基于委托的逆变 (Contravariance) 和协变 (Covariance)。

 

跨线程访问实例

不允许在winform中直接跨线程访问控件
例如:

public partial class Form1 : Form   
    {   
        public Form1()   
        {   
            InitializeComponent();   
        }   
        private void Form1_Load(object sender, EventArgs e)   
        {   
            Thread thread = new Thread(ThreadFuntion);   
            thread.IsBackground = true;   
            thread.Start();   
        }   
        private void ThreadFuntion()   
        {   
            while (true)   
            {   
                this.textBox1.Text = DateTime.Now.ToString();   
                Thread.Sleep(1000);   
            }   
        }   
    }  

会看到系统抛出一个异常:
Cross-thread operation not valid:
Control 'textBox1' accessed from a thread other than the thread it was created on .
这是因为.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.
那么怎么解决这个问题呢, 就是使用delegate和invoke来从其他线程中控制控件信息
例如:

public partial class Form1 : Form   
    {   
        private delegate void FlushClient();//代理   
        public Form1()   
        {   
            InitializeComponent();   
        }   
        private void Form1_Load(object sender, EventArgs e)   
        {   
            Thread thread = new Thread(CrossThreadFlush);   
            thread.IsBackground = true;   
            thread.Start();   
        }   
  
        private void CrossThreadFlush()   
        {   
            while (true)   
            {   
                //将sleep和无限循环放在等待异步的外面   
                Thread.Sleep(1000);   
                ThreadFunction();   
            }   
        }   
        private void ThreadFunction()   
        {   
            if (this.textBox1.InvokeRequired)//等待异步   
            {   
                FlushClient fc = new FlushClient(ThreadFunction);   
                this.Invoke(fc);//通过代理调用刷新方法   
            }   
            else  
            {   
                this.textBox1.Text = DateTime.Now.ToString();   
            }   
        }   
    }