#region Task.Run()
/*
* cpu 密集型方法:参考资料
* https://blog.csdn.net/youanyyou/article/details/78990156
*
* Task.Run() 和Task.Factory.StarNew()的区别
* https://www.cnblogs.com/wangwust/p/9493028.html
*
* https://www.cnblogs.com/zhao123/p/9999607.html
*
* Task.Run() 是Task.Factory.StarNew()的简化形式(总的来说,Task.Factory.StarNew() 可以设置线程长时间运行,所以如果需要线程长时间运行行就用Task.Factory.StarNew() 否则就用 Task.Run(),反过来,Task.Factory.StarNew() 就是 Task.Run()的原始版,比Tsak.Run 要多一些功能。比如说设置长时间运行的(线程)任务 啥的),他一般用于调用一个要求创建额外线程的cpu 密集型方法。在.net 4.5中,应该默认使
* Task.Run() 方法
*
* http://www.mamicode.com/info-detail-1780424.html
*/
//举个栗子
//public static void Main()
//{
// for (int i = 0; i < 10; i++)
// {
// Task.Factory.StartNew(() =>
// {
// try
// {
// Console.WriteLine("Task.Factory.StarNew()--- 线程id{0} --- i 的值{1}---当前时间{2}", Task.CurrentId, i, DateTime.Now);
// throw new Exception();
// }
// catch (Exception e)
// {
// Console.WriteLine("出现并抛出一个异常");
// }
// });
// Thread.Sleep(100);
// }
// for (int j = 0; j < 10; j++)
// {
// Task.Run(() =>
// {
// try
// {
// Console.WriteLine("Task.Run()---- 线程id{0} --- j 的值{1}---当前时间{2}", Task.CurrentId, j, DateTime.Now);
// }
// catch (Exception e)
// {
// Console.WriteLine("出现并抛出一个异常");
// }
// });
// }
// Task task = Task.Factory.StartNew(() => Console.WriteLine("好似天上的星,沉淀在水底的梦{0}", DateTime.Now), TaskCreationOptions.LongRunning);
// Task task = Task.Factory.StartNew(() => test());
// }
#endregion
#region TaskCreationOptions.LongRunning
/*
-
TaskCreationOptions.LongRunning 线程占用CPU的时间是由时间片(防止占用的线程过多,而卡死,
-
所以就给线程一个在处理器的运行时间,不过你有没有完成,时间到了,就把线程停止)
-
决定的,并且线程运行的很快,运行时间很短,
-
但是,如果我想让一个任务长时间运行呢?(就比如那个轮询,那个监听啥的,
-
我想让一个人就在一条路上长时间的来回奔走(公交车)那么这个人(独立的)就要是一直活跃的,又该怎么做呢?
-
TaskCreationOptions.LongRunning 就能很好的解决这个问题)
-
说明数、书上说当一个任务要长时间运行时,会霸占 一个底层线程,就可以通知调度器任务不会太快结束任务。 这个通知有两方面的作用。
-
- 他可以提醒调度器或许应该为这个要长时间运行的任务创建一个单独的线程(而不是来自线程池的,就相当于一块地,有若干部分,其中有一部分就只种一种作物,不如说西红柿,鸡蛋啥的)。
-
- 他提醒调度器可能应该调度比平时更多的线程。这样就会造成更多的时间片,有了更多的线程,就能做更多的事
-
我们不希望长时间运行的任务霸占整个处理器,让其他短时间的任务没法运行,短时间运行的任务利用分配到的时间片,能在短时间内完成大部分工作,而长时间运行的任务基本注意不到因为和其它任务共好像处理器而产生的些许延迟,为此要再调用StartNew()时使用 TackCreationOptions 选项
-
我们并不希望长时间执行的任务霸占整个处理器,就让其他短时间的任务没法运行。段时间允许的任务利用分配到底时间片,
-
在短时间内完成大部分工作,而长时间运行的任务 基本注意不到 (因为短任务执行时间段,所以个可看成是暂时将长线程挂起)
-
因为其他任务共享处理器而产生的延迟。
-
因此调用StarNeew()时应该使用 Task.Factory.StarNew() 下面的 TaskCreationOptions.LongRunning() 方法,
-
因为Task.Run() 可以说是 Task.Factory.StarNew() 的简化版 Task.Run()碰巧不支持这个长时间运行的要求,但 ask.Factory.StarNew() 下面的 TaskCreationOptions.LongRunning() 方法 可以
-
举个栗子
*///public static void Main( )
//{
// for (int i = 0; i < 100; i++)
// {
// Task task = Task.Factory.StartNew(
// () =>
// Test(i),
// TaskCreationOptions.LongRunning);
// task.Wait();
// }
//}
//public static void Test(int i)
//{
// Console.WriteLine(i);
//}
#endregion
/*
* TaskCreationOptions
*
* 指定控制创建和执行的可选行为的标志
*
* LongRunning
* 指定任务将是长期运行的粗粒度操作
*
* 那么问题来了,啥时粗粒度呢? 总的来说就是把程序看成一个房子,
* 粗粒度就是房间,细粒度就是 房间的装饰(或者说时线程占用cpu 的时间的长短) 这个东西是相对的,
* 相对于线程来说,他的粗细粒度就是他 占用cpud 的时间,又比如说数据库的设计 他的粗粒度就是他的表的数量和表和图表之间的连接,
* 或者说是他的数据表的冗余程度(数据库设计原则:挨最少的打,输出最高的仔),(冗余这东西现在还看不出来。。以后有时间研究)
* 嗯?那他的标准又是什么呢?额,为什么要有标准呢?对呀,为什么要有标准呢?哈哈
* 粗细粒度 资料参考
* https://zhidao.baidu.com/question/420895088.html
* https://blog.csdn.net/yechaodechuntian/article/details/21601659
* https://blog.csdn.net/tashanhongye/article/details/47665989
* 比细粒度系统更少、更大的组件。它提供了一个提示
* System.Threading.Tasks。
* 任务调度程序的超订阅可能是必要的。
*
* 超订阅 :总的来说,就是创建比机器能控制的更多的线程(这个多出来地线程就是要长时间运行地任务),理论上线程可以创建无数个,
* 宏观上说线程是同步的(因为CPU运算速度很快,所以可以看成时同步的),但从微观上来说,线程还是一条一条地执行的,
* 所以他可以创建无数个线程等待执行但是 容器就那么大,
* 如果线程地数量大于容器地话很可能会把容器撑坏
*
*
* 超订阅允许您创建比可用硬件数量更多的线程
* 线程。它还向任务调度程序提供了一个提示,即有一个额外的线程
* 可能需要该任务,以便它不会阻碍前进的进度
* 本地线程池队列上的其他线程或工作项。
*
*/
关于长任务和短任务的理解:
长任务,顾名思义就是长时间运行的任务,他不属于线程池,
程序会为他单独创建一个线程,在没有短任务执行时,他是一直运行的,而短任务出现时,
他会暂时让出资源,又因为短任务的执行效率很高,所以花费的时间可以忽略,(从某种意义上将他们是并行的,
就是因为他们执行效率太快,几乎可以看作是同时发生的,
因为在某一个时刻,系统只执行一个任务,就像一个人不能同时踏足两条河流一样)
处理器处理长任务和短任务的实质就是对线程的切换,
#region 匹配字符
//public static void Main()
//{
// Program t = new Program();
// t.ttt();
//}
//public void ttt()
//{
// string t = "huhuhuhuhuhhuhuhuhuhhhhhhhhhhhuhuhuhuhuhhuhuhu";
// int a = 0;
// int b = 0;
// foreach (Match m in Regex.Matches(t,"uh"))
// {
// a++;
// }
// foreach(char value in t)
// {
// if (Convert.ToString(value) =="h")
// b++;
// }
// Console.WriteLine("这个使用正则写的{0} \n 这个是用foreach写的{1}", a,b);
//}
#endregion