比如有三个步骤step1, step2, step3顺序执行,问题是step2比较耗时,想使用多线程来做,但是在这期间又不想主界面卡住,至少可以拖动主界面。怎么做啊。
main()
{
step1();
var _wait = new EventWaitHandle(false, EventResetMode.ManualReset);
System.Threading.ThreadPool.QueueUserWorkItem(delegate
{
step2();
_wait.Set();
});
_wait.WaitOne();
step3();
}
这样做可以多线程,也能顺序执行,可是会卡住主线程界面
何必这么麻烦呢
来点指导啊
@代码小兵的成长: 开启一个线程执行step2,执行完了回调step3就搞定了
@上帝之城: 嗯嗯,这个方法好,我试试
不懂多线程就多看看书多练习。
实在没兴趣看书, 你可以先花几分钟时间看看怎么使用BackgroundWorker,这个基本可以解决你目前遇到的问题。
用不了,这个方法不由界面出发,在底层,我继续找找多线程的办法
用不了,这个方法不由界面出发,在底层,我继续找找多线程的办法
@代码小兵的成长: 谁告诉你Backgroundworker只能在界面出发才能用?
@爱编程的大叔: 额额,回家我研究,我看的大概就排除 了,回家研究
你把所有步骤放在一个新的线程去执行
所有步骤又有的步骤里涉及到跨线程访问控件的事,所以在其中step2用多线程而已
@代码小兵的成长:
你这等同
step1();
step2();
step3();
@代码小兵的成长: 如果step3不需要等待step2,你就把_wait的代码去掉
@Yu: 就是因为需要等待step2,才用的这个笨方法
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; }); }
大婶,你这个辛辛苦苦帮我半天,也不给我说一点啥,我回家了再研究把,先考虑回调函数
你既然都知道使用线程池了,为什么不把main函数里写的这些代码都封装成一个函数,然后再放在一个线程池队列里呢?
另外 jello chen的方法就很好,你完全可以照抄
主要是因为main函数里的方法有的是要操作控件的,有的不需要,比如step2()就不需要,我想直接用多线程做。我要研究一下楼上的做法,我还不懂呢
@代码小兵的成长:
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")); }
亲测无误
@Troy123: 大哥真的感谢你,和 jello chen一样都是牺牲自己休息时间,多谢了,我本来想用遮罩层来做呢,您老给的这个ContinueWith的还是第一次看到,不过意思我看懂了,我再试试,应该可以的