以下是代码: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.IO;namespace 同步调用与异步调用
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }        string SelectPath;
        private void button2_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            SelectPath = folderBrowserDialog1.SelectedPath;
        }        //同步调用
        private void Asynchronousjisuan(object sender, EventArgs e)
        {
            richTextBox1.Text += "文件夹大小为" + Asynchronouscall(SelectPath) / (1024 * 1024) + "M\n" +
                                                   Asynchronouscall(SelectPath) / 1024 + "KB\n" +
                                                   Asynchronouscall(SelectPath) + "B\n\n";
        }        //定义委托
        private delegate long Asynchronouscalldelegate(string selectPath);
        //异步调用
        private void UnAsynchronousjisuan(object sender, EventArgs e)
        {
            Asynchronouscalldelegate d = new Asynchronouscalldelegate(Asynchronouscall);
            IAsyncResult ret = d.BeginInvoke(SelectPath,null, null);
            richTextBox1.Text += "正在计算当中,请稍候...\n";
            long all = d.EndInvoke(ret);
            richTextBox1.Text += "文件夹大小为" +all  / (1024 * 1024) + "M\n" +
                                              all / 1024 + "KB\n" +
                                              all + "B\n\n";
            
        }        private void RemoveAll()
        {
            button1.Click -= Asynchronousjisuan;
            button1.Click -= UnAsynchronousjisuan;
        }
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked == true)
            {
                RemoveAll();
                button1.Click += Asynchronousjisuan;
            }
        }        
        private long Asynchronouscall(string selectPath)
        {
            DirectoryInfo ThisDir = new DirectoryInfo(selectPath);
            DirectoryInfo[] ChildDirs = ThisDir.GetDirectories();
            FileInfo[] files = ThisDir.GetFiles();
            long totalsize = 0;
            foreach (FileInfo file in files)
            {
                totalsize += file.Length;
            }
            foreach (DirectoryInfo ChildDir in ChildDirs)
            {
                totalsize += Asynchronouscall(ChildDir.FullName);
            }
            return totalsize;
        }        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked == true)
            {
                RemoveAll();
                button1.Click += UnAsynchronousjisuan;
            }
        }
    }
}我不明白的是,代码是对的啊!但是在进行异步调用的时候还是要等到计算出来结果了之后才能够在richtextbox看到"正在计算当中,请稍候...\n"这句和 结果 ,不过异步调用肯定是对的,因为在进行异步计算的时候明显时间变短了。不过我就不明白了,在异步调用begin之后为何richTextBox1.Text += "正在计算当中,请稍候...\n";这句的执行效果不能够立即出现呢?我朋友用VS2010实验是对的,我是VS2008,

解决方案 »

  1.   

    把对richTextBox1的操作放入到另一个delegate中,并使用Invoke
      

  2.   

    楼上两位似乎没有针对楼主的意思回答,楼主是问为什么“用VS2010实验是对的,我是VS2008不行”,可见代码本身应该没有问题才对。
      

  3.   

    问题找到了,楼主你只要在你的
    richTextBox1.Text += "正在计算当中,请稍候...\n";
    后面添加这么一句就OK了
    richTextBox1.Refresh();
      

  4.   

    楼上谢谢咯,你的方法解决了那个问题,但是能解释下原因吗(在DOS情况下为什么不会出现这样的情况呢)?还有在用异步调用的时候为什么使用endinvoke会使主窗口锁死呢(主线程反复询问异步线程是否进行完的原因?)?,这样说来岂不是异步调用必须要使用异步回调才能达到真正的目的?还有异步回调那个函数里面又不能使用主线程的东西(因为是在异步线程里不能够使用那个吧?),比如richtextbox1(=、-郁闷了。。),那有什么有什么方法实现回调的时候动态修改主线程窗口里面的东西呢?
    问的东西比较多了。。=、-,不好意思,我才接触这个,忘各位大侠指教呀~
      

  5.   

    endinvoke就是为了把主窗口锁住才存在的方法,它是要等到异步调用结束才会释放。
    那么异步调用似乎失去了它的意义,其实不是,你在BeginInvoke后面就可以执行你想要的方法,而同时异步调用的方法也在执行,两者不冲突。调用EndInvoke就意味着你主窗口的任务完成了,只要等待异步调用返回就可以了,所以主窗口被锁住了。但无论怎样,这段过程主窗口肯定是无法动弹的,除非你不要使用异步调用,使用多线程回调就可以很好的解决主窗口被锁住的问题。你在主窗口创建一个线程,然后开始它,这时候主窗口执行少量的方法后就停下来了,但是那个新的线程还在执行,但不会锁住你的主窗口。在你的新线程里面使用this.Invoke方法让主线程操作你想要修改的窗口里面的东西,就可以在用户感觉不到的情况下修改界面上的内容了。
      

  6.   

     richTextBox1.Text += "正在计算当中,请稍候...\n";
    向上移一行
    在BeginInvoke时已经锁定
      

  7.   

    那你是怎么想到使用richtextbox1.refresh()的呢?呵呵
      

  8.   


    不是吧,你这个还没想通?首先得确定那个BeginInvoke与EndInvoke之间的代码肯定不会给锁住,能够立刻执行的,这个只要用MessageBox.Show()测试一下就知道了,马上就弹出一个窗口的。那么问题就是richtextbox1为什么没有马上更新它的内容了,所能想到的就只有它的refresh()方法了。因为主线程在忙的时候不会刷新richtextbox1,它会得在空闲的时候才会自动刷新窗口(VS2010好像直接刷新了),但是你主线程没有空闲的时候啊,你立即执行了EndInvoke把主线程给锁住了,导致来不及刷新那个richtextbox1,那么只要在调用EndInvoke之前手工刷新一下richtextbox1就可以了。