大牛们快来,这两句代码哪不一样?

hiose89 2016-09-03 10:22:56
[b]--------------------------------1.----------------------------------------------------------

Task<bool> t = Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(1000);
return true;
}
);
if(t.Result) {xxxxxxxx将要做的事xxxxxxxx}

--------------------------------2.---------------------------------------------------------
Task task= new Task(() => System.Threading.Thread.Sleep(1000));
task.Start();
task.ContinueWith(t => xxxxxxxx将要做的事xxxxxxx);
[/b]
...全文
715 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
hiose89 2016-09-05
  • 打赏
  • 举报
回复
不是说需要返回值就会阻塞主线程,而是说返回值在哪里调用。你的第一个例子返回值在主线程调用,那么主线程肯定要等到启动的线程返回后才会继续执行。如果不希望阻塞主线程,后续任务又需要根据前面的任务返回来决定如何执行,那么在延续任务中获取result就可以了,这样就不会阻塞主线程,例如第二个例子可以改成这样

Task<bool> task = Task.Factory.StartNew(() =>
{
	System.Threading.Thread.Sleep(1000);
	return true;
});
task.Start();
task.ContinueWith(t => {
	if (t.Result)
		xxxxxxxx将要做的事xxxxxxx
});
另外关于多线程task或是任务延续的一些知识,也可以参考 这里[/quote] 我懂了,意思就算是返回值在UI线程中了也是会阻塞,我原来以为不会。 我实际在我源码中有一堆方法,每个方法可能都有几百行,其中不定时的需要休眠。 所以我要拿返回值 不是为了真的为了拿返回值。 因为需求,必须要等到时间够,不然不准执行后面的代码,但又不能出现卡顿影响到UI的操作。。 要不然你上一句刚SLEEP 下面所有的代码全执行了。SLEEP时间根本还没到。 如果不用线程,界面又会卡~~~~~~ TASK也是刚刚了解。没有找到讲的很好的文章。而且我更喜欢实战,光看文章 字一多就会比较头痛。
bb_Sam 2016-09-05
  • 打赏
  • 举报
回复
引用 9 楼 hiose89 的回复:
[quote=引用 8 楼 masanaka 的回复:] Task.Factory.StartNew和new Task -> Start是一样的。 Task.Factory.StartNew是不会阻塞的,你所说的阻塞,是因为T.Result。 你举例的这两句,区别不在于用没用Factory,区别在于用没用ContinueWith,ContinueWith是Async的。 当你调用T.Result的时候,是一定要等Task执行完才继续处理调用线程的。 比方说,你开了Task后,需要主线程Do something后再去等待Task结束做“xxxxxxxx将要做的事xxxxxxxx”,这个需求用ContinueWith来处理是不合理的,因为你要确保主线程Do something先执行完。 又比方说,你开了Task后,主线程在Do一个很长的Something的同时,无需Something被Do完,只要Task结束就去做“xxxxxxxx将要做的事xxxxxxxx”,这个需求不用ContinueWith就比较麻烦了。 多线程是需要联系上下文环境的需求来理解的,单独几行代码,其实是很难来理解Task的用法的。
意思每当需要返回值就的时候就会阻塞,那我何必开个线程[/quote] 不是说需要返回值就会阻塞主线程,而是说返回值在哪里调用。你的第一个例子返回值在主线程调用,那么主线程肯定要等到启动的线程返回后才会继续执行。如果不希望阻塞主线程,后续任务又需要根据前面的任务返回来决定如何执行,那么在延续任务中获取result就可以了,这样就不会阻塞主线程,例如第二个例子可以改成这样

Task<bool> task = Task.Factory.StartNew(() =>
{
	System.Threading.Thread.Sleep(1000);
	return true;
});
task.Start();
task.ContinueWith(t => {
	if (t.Result)
		xxxxxxxx将要做的事xxxxxxx
});
另外关于多线程task或是任务延续的一些知识,也可以参考 这里
xuzuning 2016-09-05
  • 打赏
  • 举报
回复
这就同步了两件事 而你的第二段代码是在,完成第一件事情的同时,异步 做些第二件事情的后续工作
gengchenhui 2016-09-05
  • 打赏
  • 举报
回复
引用 11 楼 hiose89 的回复:
[quote=引用 10 楼 sp1234 的回复:] 例如msdn 上涉及线程同步、通讯基础功能的范例基本上都是 很糟糕的。因为这涉及到“设计思想”,不是随随便便抠点语法就能理解。很显然 msdn 的这部分的作者,没有仔细考虑,最初写那些文档的人可能只是一些实习的大学生。 对于知识讲解基本语法的例子,如果这个功能是比较高级的,你反而会觉得“似乎没有必要”。越是低级的你反而越是觉得容易理解。
首先,这不是举例,他就是我实际上思考的问题,谁不是从菜鸟过来的,难道连问问题,连想知道其中原由的权利都没有么。 知识当然先是不理解,然后你才会想去弄懂他,你不明白其中原理,又如何了解他。 带返回值的现在在我的逻辑里,我目前还找不到 他比不开线程的优势在哪。 你知道你为什么不帮别人,举个别人不就懂了。 何必在这嘲讽什么高低级 。[/quote] 你曲解他的意思了吧?高级低级不是说人。。。
xuzuning 2016-09-05
  • 打赏
  • 举报
回复
你自己也知道你的第一段代码实际上就是 System.Threading.Thread.Sleep(1000); {xxxxxxxx将要做的事xxxxxxxx} 但事情远没有 System.Threading.Thread.Sleep(1000); 这么简单 如果你打算同时做两件事情,而这两件事情都有大量 IO 操作(否则多线程就没有意义了) 并且完成第一件事情的途中需依赖第二件事情的结果
Task<bool> t = Task.Factory.StartNew(() =>  { 第二件事情(); return true; });
做第一件事的前半段
if(t.Result) { ..... }
继续完成未尽事业
hiose89 2016-09-05
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
例如msdn 上涉及线程同步、通讯基础功能的范例基本上都是 很糟糕的。因为这涉及到“设计思想”,不是随随便便抠点语法就能理解。很显然 msdn 的这部分的作者,没有仔细考虑,最初写那些文档的人可能只是一些实习的大学生。 对于知识讲解基本语法的例子,如果这个功能是比较高级的,你反而会觉得“似乎没有必要”。越是低级的你反而越是觉得容易理解。
首先,这不是举例,他就是我实际上思考的问题,谁不是从菜鸟过来的,难道连问问题,连想知道其中原由的权利都没有么。 知识当然先是不理解,然后你才会想去弄懂他,你不明白其中原理,又如何了解他。 带返回值的现在在我的逻辑里,我目前还找不到 他比不开线程的优势在哪。 你知道你为什么不帮别人,举个别人不就懂了。 何必在这嘲讽什么高低级 。
  • 打赏
  • 举报
回复
例如msdn 上涉及线程同步、通讯基础功能的范例基本上都是 很糟糕的。因为这涉及到“设计思想”,不是随随便便抠点语法就能理解。很显然 msdn 的这部分的作者,没有仔细考虑,最初写那些文档的人可能只是一些实习的大学生。 对于知识讲解基本语法的例子,如果这个功能是比较高级的,你反而会觉得“似乎没有必要”。越是低级的你反而越是觉得容易理解。
hiose89 2016-09-05
  • 打赏
  • 举报
回复
引用 8 楼 masanaka 的回复:
Task.Factory.StartNew和new Task -> Start是一样的。 Task.Factory.StartNew是不会阻塞的,你所说的阻塞,是因为T.Result。 你举例的这两句,区别不在于用没用Factory,区别在于用没用ContinueWith,ContinueWith是Async的。 当你调用T.Result的时候,是一定要等Task执行完才继续处理调用线程的。 比方说,你开了Task后,需要主线程Do something后再去等待Task结束做“xxxxxxxx将要做的事xxxxxxxx”,这个需求用ContinueWith来处理是不合理的,因为你要确保主线程Do something先执行完。 又比方说,你开了Task后,主线程在Do一个很长的Something的同时,无需Something被Do完,只要Task结束就去做“xxxxxxxx将要做的事xxxxxxxx”,这个需求不用ContinueWith就比较麻烦了。 多线程是需要联系上下文环境的需求来理解的,单独几行代码,其实是很难来理解Task的用法的。
意思每当需要返回值就的时候就会阻塞,那我何必开个线程
D56233577 2016-09-04
  • 打赏
  • 举报
回复
引用 2 楼 hiose89 的回复:
[quote=引用 1 楼 D56233577 的回复:] 如果上面执行t.Result的是UI线程,那么UI会阻塞1秒钟,下面用延续任务则不会。
从字面上来理不都是 先在后台线程中休息一秒 然后再执行吗[/quote] 要说结果其实是一样的,但上面调用线程必须等待前面的任务完成,所以调用线程会被阻塞相同的时间,而下面是任务的延续,不会阻塞调用线程。 你把代码放到事件处理程序中就可以看出区别了,Sleep时间可以放长一点。
摇撼大地 2016-09-04
  • 打赏
  • 举报
回复
task用的都是task。delay
hiose89 2016-09-04
  • 打赏
  • 举报
回复
引用 1 楼 D56233577 的回复:
如果上面执行t.Result的是UI线程,那么UI会阻塞1秒钟,下面用延续任务则不会。
从字面上来理不都是 先在后台线程中休息一秒 然后再执行吗
masanaka 2016-09-04
  • 打赏
  • 举报
回复
Task.Factory.StartNew和new Task -> Start是一样的。 Task.Factory.StartNew是不会阻塞的,你所说的阻塞,是因为T.Result。 你举例的这两句,区别不在于用没用Factory,区别在于用没用ContinueWith,ContinueWith是Async的。 当你调用T.Result的时候,是一定要等Task执行完才继续处理调用线程的。 比方说,你开了Task后,需要主线程Do something后再去等待Task结束做“xxxxxxxx将要做的事xxxxxxxx”,这个需求用ContinueWith来处理是不合理的,因为你要确保主线程Do something先执行完。 又比方说,你开了Task后,主线程在Do一个很长的Something的同时,无需Something被Do完,只要Task结束就去做“xxxxxxxx将要做的事xxxxxxxx”,这个需求不用ContinueWith就比较麻烦了。 多线程是需要联系上下文环境的需求来理解的,单独几行代码,其实是很难来理解Task的用法的。
  • 打赏
  • 举报
回复
不该 --> 不敢
  • 打赏
  • 举报
回复
引用 5 楼 hiose89 的回复:
task.ContinueWith 不也是要等到线程中的方法执行完后 才会执行吗 线程中做的事是休息一秒,一秒过后执行task.ContinueWith 带返回的Task.Factory.StartNew也先要执行线程里的方法,线程中做的事也是休息一秒,一秒后继续执行。 如果带返回的Task.Factory.StartNew会阻塞 那意思就是和不开线程一样 直接这样就行了 System.Threading.Thread.Sleep(1000); {xxxxxxxx将要做的事xxxxxxxx} 那完全没有用他的必要啊 我有点理解不过来
这是为了举例,是故意弄出来的例子。你要是“当真”,那就应该自己用“理解的结果”去设计自己的程序,而不是硬要抄人家代码。 幸好你有这个想法。有的人连这个都不该怀疑呢,盲目抄例子。这些例子就是已给极端的举例,只是用来说明个别语句,往往不为“应该如何设计”的做考虑(考虑过的更加实用的例子,许多人也不理解)。
hiose89 2016-09-04
  • 打赏
  • 举报
回复
引用 4 楼 D56233577 的回复:
[quote=引用 2 楼 hiose89 的回复:] [quote=引用 1 楼 D56233577 的回复:] 如果上面执行t.Result的是UI线程,那么UI会阻塞1秒钟,下面用延续任务则不会。
从字面上来理不都是 先在后台线程中休息一秒 然后再执行吗[/quote] 要说结果其实是一样的,但上面调用线程必须等待前面的任务完成,所以调用线程会被阻塞相同的时间,而下面是任务的延续,不会阻塞调用线程。 你把代码放到事件处理程序中就可以看出区别了,Sleep时间可以放长一点。[/quote] task.ContinueWith 不也是要等到线程中的方法执行完后 才会执行吗 线程中做的事是休息一秒,一秒过后执行task.ContinueWith 带返回的Task.Factory.StartNew也先要执行线程里的方法,线程中做的事也是休息一秒,一秒后继续执行。 如果带返回的Task.Factory.StartNew会阻塞 那意思就是和不开线程一样 直接这样就行了 System.Threading.Thread.Sleep(1000); {xxxxxxxx将要做的事xxxxxxxx} 那完全没有用他的必要啊 我有点理解不过来
D56233577 2016-09-03
  • 打赏
  • 举报
回复
如果上面执行t.Result的是UI线程,那么UI会阻塞1秒钟,下面用延续任务则不会。

111,129

社区成员

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

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

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