首页 新闻 会员 周边

c# winform 多线程简单问题

0
悬赏园豆:10 [已解决问题] 解决于 2016-05-18 16:51

比如有三个步骤step1, step2, step3顺序执行,问题是step2比较耗时,想使用多线程来做,但是在这期间又不想主界面卡住,至少可以拖动主界面。怎么做啊。

main()

{

  step1();

  var _wait = new EventWaitHandle(false, EventResetMode.ManualReset);

  System.Threading.ThreadPool.QueueUserWorkItem(delegate
  {  

    step2();

    _wait.Set();

  });

  _wait.WaitOne();

  step3();

}

 

这样做可以多线程,也能顺序执行,可是会卡住主线程界面

代码小兵的成长的主页 代码小兵的成长 | 菜鸟二级 | 园豆:303
提问于:2016-05-18 11:44
< >
分享
最佳答案
0

何必这么麻烦呢

收获园豆:3
上帝之城 | 老鸟四级 |园豆:2549 | 2016-05-18 11:52

来点指导啊

代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 13:29

@代码小兵的成长: 开启一个线程执行step2,执行完了回调step3就搞定了

上帝之城 | 园豆:2549 (老鸟四级) | 2016-05-18 14:08

@上帝之城: 嗯嗯,这个方法好,我试试

代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 16:48
其他回答(4)
0

不懂多线程就多看看书多练习。

实在没兴趣看书, 你可以先花几分钟时间看看怎么使用BackgroundWorker,这个基本可以解决你目前遇到的问题。

收获园豆:1
爱编程的大叔 | 园豆:30839 (高人七级) | 2016-05-18 11:57

用不了,这个方法不由界面出发,在底层,我继续找找多线程的办法

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 13:27

用不了,这个方法不由界面出发,在底层,我继续找找多线程的办法

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 13:27

@代码小兵的成长: 谁告诉你Backgroundworker只能在界面出发才能用?

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2016-05-18 14:09

@爱编程的大叔: 额额,回家我研究,我看的大概就排除 了,回家研究

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 16:50
0

你把所有步骤放在一个新的线程去执行

收获园豆:1
Yu | 园豆:12980 (专家六级) | 2016-05-18 12:53

所有步骤又有的步骤里涉及到跨线程访问控件的事,所以在其中step2用多线程而已

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 13:17

@代码小兵的成长:

你这等同

step1(); 

step2();

step3();

支持(0) 反对(0) Yu | 园豆:12980 (专家六级) | 2016-05-18 13:50

@代码小兵的成长: 如果step3不需要等待step2,你就把_wait的代码去掉

支持(0) 反对(0) Yu | 园豆:12980 (专家六级) | 2016-05-18 14:01

@Yu: 就是因为需要等待step2,才用的这个笨方法

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 14:09
1
private async void Work()
        {
            await DoStep1();
            await DoStep2();
            await DoStep3();
        }

        private async Task<string> DoStep1()
        {
            return await Task.Run(() =>
                {
                    Thread.Sleep(3000);
                    var step = "step 1";
                    this.BeginInvoke(new Action(() =>
                        {
                            label1.Text = step;
                        }));
                    return step;
                });
        }
        private async Task<string> DoStep2()
        {
            return await Task.Run(() =>
            {
                Thread.Sleep(5000);
                var step = "step 2";
                this.BeginInvoke(new Action(() =>
                {
                    label1.Text = step;
                }));
                return step;
            });
        }
        private async Task<string> DoStep3()
        {
            return await Task.Run(() =>
            {
                Thread.Sleep(3000);
                var step = "step 3";
                this.BeginInvoke(new Action(() =>
                {
                    label1.Text = step;
                }));
                return step;
            });
        }

 

收获园豆:5
jello chen | 园豆:7306 (大侠五级) | 2016-05-18 13:47

大婶,你这个辛辛苦苦帮我半天,也不给我说一点啥,我回家了再研究把,先考虑回调函数

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-18 16:50
0

你既然都知道使用线程池了,为什么不把main函数里写的这些代码都封装成一个函数,然后再放在一个线程池队列里呢?

另外 jello chen的方法就很好,你完全可以照抄

韩子卢 | 园豆:202 (菜鸟二级) | 2016-05-24 09:37

主要是因为main函数里的方法有的是要操作控件的,有的不需要,比如step2()就不需要,我想直接用多线程做。我要研究一下楼上的做法,我还不懂呢

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-24 13:29

@代码小兵的成长: 

 private void btnShow_Click(object sender, EventArgs e)
        {
            Step1();//第一步,因为你现在还在UI线程,所以会阻塞,然而这里的阻塞只是模拟你进行的操作
            Task taskForStep2 = new Task(() => Step2());
            taskForStep2.ContinueWith(task1 => Step3());
            taskForStep2.Start();
            //第二步进入了多线程,所以不阻塞了
            //第三步在第二步执行完后执行,同样是多线程,不阻塞
        }

        public void Step1() {
            Thread.Sleep(5000);//模拟你进行的操作
            this.BeginInvoke(new Action(() => tetxBoxShow.Text = "Step1"));//模拟你进行的UI操作
        }
        public void Step2()
        {
            Thread.Sleep(5000);
            this.BeginInvoke(new Action(()=> tetxBoxShow.Text = "Step2"));
        }
        public void Step3()
        {
            Thread.Sleep(5000);
            this.BeginInvoke(new Action(() => tetxBoxShow.Text = "Step3"));
        }

亲测无误

支持(1) 反对(0) 韩子卢 | 园豆:202 (菜鸟二级) | 2016-05-25 23:27

@Troy123: 大哥真的感谢你,和 jello chen一样都是牺牲自己休息时间,多谢了,我本来想用遮罩层来做呢,您老给的这个ContinueWith的还是第一次看到,不过意思我看懂了,我再试试,应该可以的

支持(0) 反对(0) 代码小兵的成长 | 园豆:303 (菜鸟二级) | 2016-05-26 09:40
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册