今天看委托的同步与异步调用,看的我蛋好痛首先是:Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的? 这个我首先就没怎么理解。其实看那个工作线程同步更新UI,看的闷,感觉似懂,非懂。还看到一段话非常有道理,但具体不知道怎么体现到程序里。这段话是这样的“用工作线程去更新界面,在多线程中直接调用界面控件的方法是错误的,正确的做法是将工作线程中涉及到更新界面
的代码封装起来,通过invoke或者begin invoke来调用。(这里在代码里就不懂怎么实现了。)两者的区别就是一个导致工作线程等待,一个则不会。有哪位好心的老大帮忙解释下吧最好弄个例子或者我发个例子using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsApplication4
{
    /**/
    /// <summary>
    /// gui 类
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //用子线程工作
            new System.Threading.Thread(new System.Threading.ThreadStart(StartDownload)).Start();
        }        //开始下载
        public void StartDownload()
        {
            Downloader downloader = new Downloader();
            downloader.onDownLoadProgress += new Downloader.dDownloadProgress(downloader_onDownLoadProgress);
            downloader.Start();
        }
        //同步更新ui
        void downloader_onDownLoadProgress(long total, long current)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Downloader.dDownloadProgress(downloader_onDownLoadProgress), new object[] { total, current });
            }
            else
            {
                this.progressBar1.Maximum = (int)total;
                this.progressBar1.Value = (int)current;
            }
        }
    }                     //重点是这段,    /**/
    /// <summary>
    /// 下载类
    /// </summary>
    public class Downloader
    {
        //委托
        public delegate void dDownloadProgress(long total, long current);
        //事件
        public event dDownloadProgress onDownLoadProgress;
        //开始模拟工作
        public void Start()
        {
            for (int i = 0; i < 100; i++)
            {
                if (onDownLoadProgress != null)
                    onDownLoadProgress(100, i);
                System.Threading.Thread.Sleep(100);
            }
        }
    }
}我不能再看了,头要爆炸了。明天来看看各位的回复、、、另外我没分了。。不好意思,就30了

解决方案 »

  1.   

            private void button1_Click(object sender, EventArgs e)
            {
                Thread t = new Thread(new ThreadStart(ThreadMethod));
                t.Start();
            }
            void ThreadMethod()
            {
                label1.Text = "从非UI线程中修改。。";// 在这里会异常。。
                // 线程间操作无效: 从不是创建控件“label1”的线程访问它。。
            }正确做法如下:        private void button1_Click(object sender, EventArgs e)
            {
                Thread t = new Thread(new ThreadStart(ThreadMethod));
                t.Start();
            }
            void ThreadMethod()
            {
                this.Invoke(new MyDelegate(DelegateMethod), "通过委托跨县城访问。。");
            }
            delegate void MyDelegate(string param);
            void DelegateMethod(string param)
            {
                label1.Text = param;
            }
      

  2.   

    UI更新代码集中到 DelegateMethod 这个方法中。。
    更新所需参数集中到 param 中,如果有多个参数可以用泛型封成一个对象。。
      

  3.   

    Invoke就是直接运行,BeginInvoke是开启另一个辅助线程运行
    调用Invoke是利用反射在执行
    Delegate的BeginInvoke是在新的线程执行的,Control.BeginInvoke是在创建Control的线程里执行的
      

  4.   

    invoke就是调用的意思
    Control的Invoke和BeginInvoke 一般是在非创建控件的进程中使用,以调用和控件操作有关的方法,你先看看多线程吧 
      

  5.   

    这个我正在做,可以给你点提示:
    首先定义变量public static Form1 from;
    在你调用方法类Downloader里面也设置一个变量Form1 mainform;
    且构造函数为:
    public override void init(Form1 from)
            {
                this.mainform = from;
            }
    启动调用线程的时候给方法类赋值
    Downloader.init(form);
    下面的泪一定要写在主form里
    public  void UpdateMessageList(string msg)
            {            BeginInvoke(new myDelegate(delegate()
                {
                   /** if (listBoxMsg.Items.Count > 100)
                    {
                        listBoxMsg.Items.RemoveAt(0);
                    }*/
                    //listBoxMsg.SelectedIndex = listBoxMsg.Items.Add(msg);
                    textBox1.Text +=msg;
                    this.textBox1.Focus();//获取焦点
                    this.textBox1.Select(this.textBox1.TextLength, 0);//光标定位到文本最后
                    this.textBox1.ScrollToCaret();//滚动到光标处
                })); 
            }在执行线程里调用
     this.mainform.UpdateMessageList(string);就能实现,且不会报错
      

  6.   

     private void button1_Click(object sender, EventArgs e)
            {
                Thread t = new Thread(new ThreadStart(ThreadMethod));
                t.Start();
            }
            void ThreadMethod()
            {
                this.Invoke(new MyDelegate(DelegateMethod), "通过委托跨县城访问。。");
            }
            delegate void MyDelegate(string param);
            void DelegateMethod(string param)
            {
                label1.Text = param;
            }
      

  7.   

    invoke和begininvoke都是讲工作线程中修改UI的代码委托给主线程(UI线程)来实现UI的修改,不同的是invoke是同步的,也就是说工作线程将修改UI的函数用invoke来委托给主线程后,要等待主线程修改完UI,工作线程才能继续执行下去,而begininvoke是异步的,也就是说工作线程把修改UI的任务委托给主线程之后不管主线程当前是否有空去修改UI,工作线程都会继续执行下去
      

  8.   

    一个简单的例子using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace doWorker
    {
        public partial class Form1 : Form
        {
            delegate void MyDelegate(int value);
            Thread t;
            int i = 0;
            public Form1()
            {
                InitializeComponent();
            }        // 在新的线程中做“需要长时间做的”工作
            private void button1_Click(object sender, EventArgs e)
            {
                t = new Thread(doWork);
                t.Start();
            }        // 要长时间做的工作
            void doWork()
            {
                MyDelegate d = new MyDelegate(setValue);
                while (true)
                {
                    ++i;
                    this.Invoke(d, i);
                    Thread.Sleep(100);
                }
            }        // 更新用户界面
            void setValue(int value)    
            {
                label1.Text = value.ToString();
            }        // 终止线程的执行
            private void button2_Click(object sender, EventArgs e)
            {
                t.Abort();
            }    }
    }
      

  9.   

      //同步更新ui
      void downloader_onDownLoadProgress(long total, long current)
      {
      if (this.InvokeRequired)
      {
      this.Invoke(new Downloader.dDownloadProgress(downloader_onDownLoadProgress), new object[] { total, current });
      }
      else
      {
      this.progressBar1.Maximum = (int)total;
      this.progressBar1.Value = (int)current;
      }
      }
      }
    谁能给我解释下这里? if (this.InvokeRequired) 及其下面的
      

  10.   

    近期准备写一个多线程的基于Tcp/IP的微型服务器。学习