C#使用task時候假面卡死

martin_tang 2017-02-27 05:13:36
下面的代碼是測試使用3個task去執行count_wast_time()這個函數;然後再畫面上面顯示“count_wast_time 開始”;但是一旦添加 Task.WaitAll界面就卡死了,為什麼??
求告知錯誤的原因,還有如何合理的修改


```
private void button3_Click(object sender, EventArgs e)
{
var tasks = new Task[3];
int i = 0;
int j = 0;
int k = 0;

a2 = 0;
string s1 = "";

tasks[0] = Task.Factory.StartNew(() =>
{
count_wast_time();
}
);

tasks[1] = Task.Factory.StartNew(() =>
{
count_wast_time();
}
);

tasks[2] = Task.Factory.StartNew(() =>
{
count_wast_time();
}
);
Task.WaitAll(tasks[0], tasks[1], tasks[2]); //???出問題

label3.Text = label3.Text + "全部執行完畢";
}

```


```
private void count_wast_time()
{
this.label3.Invoke(new Action(() =>
{
label3.Text = "count_wast_time 開始\n";
}));


for (int i2 = 0; i2 < 600; i2++)
{

for (int j2 = 0; j2 < 200; j2++)
{
for (int k3 = 0; k3< 100; k3++)
{
}
}
}
}
```



...全文
1013 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
martin_tang 2017-03-01
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
另外,一旦你有 label3.Text = label3.Text + "全部執行完畢"; 这类代码的想法的时候,要养成一个习惯,你这个 button3_Click 中的代码也应该设计为在子线程中执行的,而不能在主线程执行。 实际上我们在设计多线程程序时,要避免动不动就“死等、死循环”的思路。一旦不能避免,你应该会想到,恶性循环造成从高层到底层都需要许多子线程来处理流程,一下子就是去了程序的灵敏响应,而且还极难调试。不科学的异步流程,一旦不牺牲巨大的代价就会死锁,所以不要滥用线程。用线程之前先要将程序设计流程改为灵敏的事件驱动模式、消息启动模式。
謝謝回答, 你說的很對,特別是不能再主線程中進行死等,那樣很不好。 程式設計還是要靈活一點的,簡潔明了一點。
  • 打赏
  • 举报
回复
另外,一旦你有 label3.Text = label3.Text + "全部執行完畢"; 这类代码的想法的时候,要养成一个习惯,你这个 button3_Click 中的代码也应该设计为在子线程中执行的,而不能在主线程执行。 实际上我们在设计多线程程序时,要避免动不动就“死等、死循环”的思路。一旦不能避免,你应该会想到,恶性循环造成从高层到底层都需要许多子线程来处理流程,一下子就是去了程序的灵敏响应,而且还极难调试。不科学的异步流程,一旦不牺牲巨大的代价就会死锁,所以不要滥用线程。用线程之前先要将程序设计流程改为灵敏的事件驱动模式、消息启动模式。
  • 打赏
  • 举报
回复
我们基本上不使用 Invoke,而是使用 BeginInvoke。 你删除 count_wast_time,自己动手做测试,要比干瞪着代码去分析理论更好。
  • 打赏
  • 举报
回复
引用 2 楼 martin_tang 的回复:
[quote=引用 1 楼 xinweilee 的回复:] count_wast_time循环太耗时了,导致假死
謝謝回答, 假死之後,恢復不了了,count_wast_time()應該是很快執行完成的[/quote] 你如果把 count_wast_time 里边的代码删掉,应该是很快执行完。
martin_tang 2017-02-27
  • 打赏
  • 举报
回复
引用 3 楼 dongxinxi 的回复:
waitAll就是等待所有任务全部执行完,与同前线程同步用的,自然会卡 可以加锁,简单点也可以task内部后面加判断 if(Interlocked.Add(计数,1)== 3) 全部完成
謝謝回答, 但是不光是卡,是直接卡死,等很久都不到~~
martin_tang 2017-02-27
  • 打赏
  • 举报
回复
引用 5 楼 qq_25095899 的回复:
waitAll 就是等,等所有线程完毕,3个线程里完成了2个,还有1个没有完成也会等,总之一句话,等! 楼上已经说了,label3.Text = label3.Text + "全部執行完畢";不应该写在调用所有线程并且等待执行完后,应该加在线程调用的具体方法里,判断3个是否都已经完成了,加个参数记录完成次数, 加锁。
謝謝回答, 我知道會等,但是發現一直會等不到,開著等很久很久
大然然 2017-02-27
  • 打赏
  • 举报
回复
waitAll 就是等,等所有线程完毕,3个线程里完成了2个,还有1个没有完成也会等,总之一句话,等! 楼上已经说了,label3.Text = label3.Text + "全部執行完畢";不应该写在调用所有线程并且等待执行完后,应该加在线程调用的具体方法里,判断3个是否都已经完成了,加个参数记录完成次数, 加锁。
  • 打赏
  • 举报
回复
去掉 Task.WaitAll,然后再用LS的方法
  • 打赏
  • 举报
回复
waitAll就是等待所有任务全部执行完,与同前线程同步用的,自然会卡 可以加锁,简单点也可以task内部后面加判断 if(Interlocked.Add(计数,1)== 3) 全部完成
martin_tang 2017-02-27
  • 打赏
  • 举报
回复
引用 1 楼 xinweilee 的回复:
count_wast_time循环太耗时了,导致假死
謝謝回答, 假死之後,恢復不了了,count_wast_time()應該是很快執行完成的
xinweilee 2017-02-27
  • 打赏
  • 举报
回复
count_wast_time循环太耗时了,导致假死

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧