zoukankan      html  css  js  c++  java
  • 使用匿名函数在后台线程中设置窗体控件属性

        在使用Dotnetfx2.0开发WinForm程序时,经常需要使用后台线程来进行运算,并把运算的过程数据,结果数据等信息更新显示到窗口中。由于窗体线程和工作线程不是一个线程,我们不能在工作线程中直接设置窗体中控件的属性,而需要使用Control.Invoke(Delegate del,...)来间接调用。其实,可以使用一个匿名函数很简单的调用。

        按照MSDN上的标准作法,如果有一个函数:

    void WriteMessage(string msg)
    {
        
    this.tbMsg.Text += msg;
    }

    要在工作线程函数中调用,需要先声明一个委托:

    public delegate void WriteMessageHandle(string);

    然后在线程函数中调用:

    public void ThreadProc(object obj)
    {
         ..
         
    this.Invoke(new WriteMessageHandle(this.WriteMessag, new object[]{"hello world"}));
         ..
    }
         其实,就为了一句: this.tbMsg.Text += msg; 费了多大事呀。 其实,在C# 2.0中, 我们可以很简单:
    // 先声明这样一个万用的委托
    public delegate void VoidDelegate();

    public void ThreadProc(object obj)
    {
          
    //这是要输出的消息
          string msg = "Hello World";
          .
          
    //由于是在工作线程中,我们不用理 this.InvokeRequired,直接调用
         
    //直接使用匿名函数,这样可以使用 msg 局部变量,哈哈 简单吧
          this.Invoke(new VoidDelegate(delegate()
          {
                
    //这句就是要执行的函数了
                this.tbMsg.Text += msg;
                
                
    //这里还可以调用其它的窗体相关的代码
             
    // EX
               
    // this.tbName.Text = "my name here ";
          }));
          .
    }
    示例2:工作线程中,使用线程池进行工作,这里还有最大并发控制哟(不知道你们如何实现最大并发):
    // 先声明这样一个万用的委托
    public delegate void VoidDelegate();

    public void ThreadProc(object obj)
    {
            
    //假设,并发值为 5
            Semaphore poolLock = new Semaphore(55);
            
            
    //假设 this.WorkItems 是需要进行的工作
            foreach(WorkItem workItem in this.WorkItems)
            {
                
    //闭包
                WorkItem item = workItem; 
                
                
    //保确不超过并发最大值
                poolLock.WaitOne();
                
                
    //使用线程池进行执行,示例使用系统线程池
                ThreadPool.QueueUserWorkItem(delegate(object arg)
                {
                    
    try
                    {
                        
    //这是要输出的消息
                        string msg = item.Message; // "Hello World";
                        
                        
    //由于是在工作线程中,我们不用理 this.InvokeRequired,直接调用
                        
    //直接使用匿名函数,这样可以使用 msg 局部变量,哈哈 简单吧
                        this.Invoke(new VoidDelegate(delegate()
                        {
                            
    //这句就是要执行的函数了
                            this.tbMsg.Text += msg;
                            
                            
    //这里还可以调用其它的窗体相关的代码
                         
    // EX
                           
    // this.tbName.Text = "my name here ";
                        }));
                        
                        
                    }
                    
    finally
                    {
                        
    //最后进行释放 并发锁
                        poolLock.Release();
                    }
                });
            }
            
    }
  • 相关阅读:
    idea报“Usage of API documented as @since 1.7”这一问题的解决方法
    分页的总页数算法
    Error evaluating expression 'category.id != null and category.id != '''. Cause: org.apache.ibatis.og
    json日期处理类
    解决maven过滤必需配置文件的方法
    数据库配置文件
    springmvc 提供的统一解决json中文乱码配置
    EXPLAIN 命令详解
    MySQL索引与Index Condition Pushdown(二)
    【MySQL】性能优化之 Index Condition Pushdown
  • 原文地址:https://www.cnblogs.com/evlon/p/1589344.html
Copyright © 2011-2022 走看看