我在Windows Form主线程中,点击Button1,启动新线程(BackThread),以处理比较耗时的业务。
BackThread线程处理流程:(1-->2-->3)
1>通过Invoke(new MyDelegate(...))方式,将主线程隐藏的更新图片和Laber(lblWait)显示出来(.Visible=true), lblWait.Text="正在处理,请稍候...";2>处理业务逻辑,BackProcess(...)---该方法比较耗时,可能需要几分钟;3>业务逻辑完成,将图片和文本隐藏。结果: 虽然用多线程,仍出现假死现象。图片和文本都没有显示.BackThread运行结束后,主窗体(主线程)才恢复正常.问题: 如何通过多线程,解决主窗体假死,通过新线程来处理耗时的业务,并在主窗体中,利用动画和文本提示用户业务正在处理。同时,不影响主窗体的其他操作。请帮忙指点一下......

解决方案 »

  1.   

    你的主UI线程,在BackProcess工作的时候在做什么?waithandle么?那样也会假死。最好啥也不干,等BackProcess工作完了,通过Invoke(new MyDelegate(...)的方式,更新主线程UI。如果以上猜想不对,还请lz详细说明下BackProcess工作的时候UI线程在做什么。
      

  2.   

    BackProcess(...)就是在处理一个较大数据库的备份操作(大概5分钟左右),我想在处理这个操作时,动画gif提示用户操作正在进行,同时不阻塞主线程,让主UI可以继续进行其他操作(如:TextBox的输入,点击其他Button等)
      

  3.   

    invoke 是同步调用,使用 begininvoke
      

  4.   

    异步委托提供以异步方式调用同步方法的能力。当同步调用一个委托时,Invoke 方法直接对当前线程调用目标方法。如果编译器支持异步委托,则它将生成 Invoke 方法以及 BeginInvoke 和 EndInvoke 方法。如果调用 BeginInvoke 方法,则公共语言运行库将对请求进行排队并立即返回到调用方。将对来自线程池的线程调用该目标方法。提交请求的原始线程自由地继续与目标方法并行执行,该目标方法是对线程池线程运行的。如果已经对 BeginInvoke 指定了回调,当目标方法返回时将调用它。在回调中,使用 EndInvoke 方法来获取返回值和输入/输出参数。如果没有对 BeginInvoke 指定回调,则可以在提交请求的原始线程上使用 EndInvoke。
      

  5.   

    lz应该是在子线程中Invoke的吧?如果是的话,是否用异步代理应该问题不大。UI线程在BackProcess时具体在做什么呢?现在既然出现了假死,应该是在做些什么呢吧?
      

  6.   

    我写的测试小例子。出现阻塞
    public partial class Form1 : Form
        {
            private int i;
            private delegate void myDelegate();        public Form1()
            {
                InitializeComponent();            
            }                private void btnAlert_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Other thing is running!");
            }        private void btnStart_Click(object sender, EventArgs e)
            {
                Thread t = new Thread(new ThreadStart(RunBack));            t.Start();
            }        private void RunBack()
            {
                if (this.txtName.InvokeRequired || this.pbProcess.InvokeRequired) 
                {
                    BeginInvoke(new myDelegate(ModifyValue));
                }
            }
                    
            private void ModifyValue()
            {
                //PictureBox: pbProcess
                this.pbProcess.Visible = true;            while (i<20)
                {
                    this.txtName.Text = i.ToString();                i++;                Thread.Sleep(500);
                }
            }    }
      

  7.   

    我用一个while语句模拟耗时操作:while (i<20)
                {
                    this.txtName.Text = i.ToString();                i++;                Thread.Sleep(500);
                }
      

  8.   

    在启动新线程后,动画gif没有显示(虽然this.pbProcess.Visible = true),文本框内容不变(this.txtName.Text = i.ToString()),直到线程结束才有变化.
      

  9.   

    假死的原因倒是还没找到,不过可以提供一种不死的办法,就是用
    private System.ComponentModel.BackgroundWorker backgroundWorker1;
    this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);然后
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                while (i < 20)
                {
                    this.txtName.Invoke((MethodInvoker)delegate { this.txtName.Text = i.ToString(); });
                    i++;
                    Thread.Sleep(1000);
                }
            }
    然后
            private void btnAlert_Click_1(object sender, EventArgs e)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }
      

  10.   

    还有,就是用ThreadPool貌似也不死
      

  11.   

    同意。
    invoke 是同步调用,使用 begininvoke
      

  12.   

    Thread.Sleep你等待是在UI线程上做的,前边的操作又很快,应该是已经变了,但又sleep了。
      

  13.   

    編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com編程王10TB代碼庫
    http://code.kingofcoders.com10TB代碼Search engine
    http://search.kingofcoders.com