/// <summary>
/// Parallel並行線程
/// </summary>
public class Parallel1
{
public static Stopwatch sw = new Stopwatch();
public List<int> list1 = new List<int>();
public Dictionary<string, int> dic = new Dictionary<string, int>();
#region 並行
public void SetListOrDic()
{
sw.Stop();
sw.Restart();
for (int i = 0; i < 1000; i++)
{
list1.Add(i);
}
sw.Stop();
Console.WriteLine("執行List的時間" + sw.Elapsed);
sw.Restart();
for (int i = 0; i < 1000; i++)
{
dic.Add("dic" + i, i);
}
sw.Stop();
Console.WriteLine("執行dic的時間" + sw.Elapsed);
sw.Restart();
int s = 0;
foreach (var item in list1)
{
s += item;
}
sw.Stop();
Console.WriteLine("遍歷list的時間" + sw.Elapsed + "結果爲" + s);
sw.Restart();
int w = 0;
foreach (var item in dic)
{
w += item.Value;
}
sw.Stop();
Console.WriteLine("遍歷dic的時間" + sw.Elapsed + "結果爲" + w);
}
public static void Run1()
{
Thread.Sleep(2000);
Console.WriteLine("阻塞2000");
}
public static void Run2()
{
Thread.Sleep(3000);
Console.WriteLine("阻塞3000");
}
/// <summary>
/// 打印並行執行操作
/// </summary>
public void Run1AndRun2()
{
sw.Start();
Parallel.Invoke(Run1, Run2);//並行執行操作方法
sw.Stop();
Console.WriteLine("並行時間:" + sw.ElapsedMilliseconds);
sw.Restart();
Run1();
Run2();
sw.Stop();
Console.WriteLine("run1+run2的時間" + sw.ElapsedMilliseconds);
}
/// <summary>
/// 結束並行操作
/// </summary>
public void BreakOrStop()
{
ConcurrentBag<int> con = new ConcurrentBag<int>();//表示對線程安全的無序集合
sw.Start();
//使用stop
Parallel.For(0, 1000, (i, state) =>
{
if (con.Count() == 300)
{
state.Stop();
return;
}
con.Add(i);
});
sw.Stop();
Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);
sw.Restart();
//使用break
Parallel.For(0, 1000, (i, state) =>
{
if (con.Count() == 300)
{
state.Break();
return;
}
con.Add(i);
});
sw.Stop();
Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);
}
#endregion
}
/// <summary>
/// 並行Linq
/// </summary>
public class ParallelLinq
{
Stopwatch sq = new Stopwatch();
List<Custom> ListByCustom = new List<Custom>();
public void Plinq()
{
try
{
for (int i = 0; i < 2000000; i++)
{
ListByCustom.Add(new Custom { Adress = "adress" + i, Age = i, Name = "namne" + i });
}
#region AsParallel()表示 把當前查詢並行化
sq.Start();
var list = ListByCustom.Where(i => i.Age > 55).ToList();
sq.Stop();
Console.WriteLine("普通linq時間爲" + sq.ElapsedMilliseconds);
sq.Restart();
sq.Start();
//AsParallel()表示 把當前查詢並行化
var list1 = ListByCustom.AsParallel().Where(i => i.Age > 55).ToList();
sq.Stop();
Console.WriteLine("並行Linq時間爲" + sq.ElapsedMilliseconds);
#endregion
#region Group 與ToLookup
sq.Restart();
var listgroup = ListByCustom.GroupBy(i => i.Age).ToList();
sq.Stop();
Console.WriteLine("Group時間"+sq.ElapsedMilliseconds);
sq.Restart();
var listgroup1 = ListByCustom.ToLookup(i => i.Age).ToList();
sq.Stop();
Console.WriteLine("ToLookup時間" + sq.ElapsedMilliseconds);
#endregion
}
catch (ArgumentNullException ex)
{
Console.WriteLine(ex);
sq.Stop();
}
}
/// <summary>
/// 並行輔助類
/// </summary>
public class Custom
{
public string Name { get; set; }
public int Age { get; set; }
public string Adress { get; set; }
}
}
/// <summary>
/// Task任務,兩種創建方式
/// var t1=new Task(()=>{直接new
///
/// });
///
/// var t2=Task.Factory.StartNew(()=>{工廠模式創建
///
/// });
/// </summary>
public class GetTask {
public void GetTasks() {
//第一種創建方式 必須手動start
var t1 = new Task(() => {
Console.WriteLine("開始t1");
Thread.Sleep(1000);//阻塞1秒
Console.WriteLine("task1");
});
t1.Start();//使用new方式創建時必須手動start
///Task.Wait()等待線程完成,Task.WaiitAll()等待所有線程完成
///
t1.Wait();//等待當前線程完成才執行其他代碼
//第二種方式直接開啓
var t2 = Task.Factory.StartNew(() => {
Console.WriteLine("開始t2");
Thread.Sleep(2000);
Console.WriteLine("task2");
});
var t3 = Task.Factory.StartNew(() => {
Console.WriteLine("開始t3");
Thread.Sleep(2000);
Console.WriteLine("task3");
});
//等待所有的線程完成才執行其他代碼
//Task.WaitAll(t2,t3);
//等效的還有Task.WaitAny,表示任意線程執行完後才執行
//ContinueWith自動執行
Console.WriteLine("線程完成");
var result = t1.ContinueWith(task => {
Console.WriteLine("自動線程");
return "this is result";
});
Console.WriteLine(result.Result.ToString());
#region Task嵌套 TaskCreationOptions.AttachedToParent指定將任務附加到當前結構層次的父級 qt與pt對比
var qt = Task.Factory.StartNew(() => {
var qt1 = Task.Factory.StartNew(() => {
Thread.Sleep(1000);
Console.WriteLine("this is Child1");
});
Console.WriteLine("parent task1");
});
qt.Wait();
Console.WriteLine("當前操作主任務qt並不會等待子任務qt1執行完纔打印此消息");
var pt = Task.Factory.StartNew(() =>
{
var pt1 = Task.Factory.StartNew(() => {
Thread.Sleep(1000);
Console.WriteLine("this is Child2");
},TaskCreationOptions.AttachedToParent);
Console.WriteLine("parent Task2");
});
pt.Wait();
Console.WriteLine("主任務等待子任務執行完纔打印此消息,關鍵字的作用TaskCreationOptions.AttachedToParent");
#endregion
Console.WriteLine("----------------------------------------------------------------");
#region Task嵌套例子
//描述:
//C1得到主任務返回的1+2
//C2得到主任務返回的1+3
//C1的子任務的到C1的結果加上4
//最後,將任務合併,輸出結果
var Ztsk = Task.Factory.StartNew<int>(() => {
Console.WriteLine("開始主任務");
return 1;
});
//等待主任務完成
Console.WriteLine("結果"+Ztsk.Result);
Ztsk.Wait();
//任務C2
var C2 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始任務C2");
return Ztsk.Result + 3;
});
Console.WriteLine("結果"+C2.Result);
//任務C1
var C1 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始任務C1");
return Ztsk.Result + 2;
}).ContinueWith<int>(task => {
Console.WriteLine("開始任務C1的子任務");
return task.Result + 4;
});
Console.WriteLine("結果" + C1.Result);
//等待所有任務完成
Task.WaitAll(C1,C2);
//打印結果
Console.WriteLine("結果爲"+(C2.Result+ C1.Result));
#endregion
Console.WriteLine("-----------------------------Task多線程問題 -----------------------------------");
}
#region Task多線程問題
/* 1,死鎖
如果我們在調用Task.WaitAll方法等待所有線程時
* ,如果有一個Task一直不返回,會出現什麼情況呢?
* 當然,如果我們不做出來的話,程序會一直等待下去,
* 那麼因爲這一個Task的死鎖,導致其他的任務也無法正常提交
* ,整個程序"死"在那裏
*/
#region //死鎖例子
public void TaskError()
{var ts1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("死鎖任務");
while (true)
{
Console.WriteLine("1");
}
});
var ts2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 2");
Thread.Sleep(1000);
Console.WriteLine("結束任務");
});
Task.WaitAll(ts1, ts2);
}
#endregion
#region //解決死鎖,即設定最大等待時間,操過時間就退出
public void RemoveSs() {
Task[] task = new Task[2];
task[0] = Task.Factory.StartNew(() => {
Console.WriteLine("Task 1 Start running...");
while (true)
{
Thread.Sleep(3000);
Console.WriteLine("Task 1 Finished!");
}
});
task[1] = Task.Factory.StartNew(() => {
Console.WriteLine("Task 2 Start running...");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 2 Finished!");
});
//等待的最大時間 爲5秒
Task.WaitAll(task,5000);
for (int i = 0; i < task.Length; i++)
{
if (task[i].Status!=TaskStatus.RanToCompletion)
{
Console.WriteLine("任務{0}沒有執行完",task[i].Id);
}
}
}
#endregion
#endregion
#region 計算例子
public void GetResult() {
bool su = false;
var t1 = Task.Factory.StartNew<int>(() => {
Console.WriteLine("第一個數字");
return 1;
});
t1.Wait();
var t2 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始計算");
return 5;
}).ContinueWith(state => {
if ((t1.Result + state.Result) >= 6)
Console.WriteLine("大於");
else
{
Console.WriteLine("不大於");
}
});
}
#endregion
}
/// Parallel並行線程
/// </summary>
public class Parallel1
{
public static Stopwatch sw = new Stopwatch();
public List<int> list1 = new List<int>();
public Dictionary<string, int> dic = new Dictionary<string, int>();
#region 並行
public void SetListOrDic()
{
sw.Stop();
sw.Restart();
for (int i = 0; i < 1000; i++)
{
list1.Add(i);
}
sw.Stop();
Console.WriteLine("執行List的時間" + sw.Elapsed);
sw.Restart();
for (int i = 0; i < 1000; i++)
{
dic.Add("dic" + i, i);
}
sw.Stop();
Console.WriteLine("執行dic的時間" + sw.Elapsed);
sw.Restart();
int s = 0;
foreach (var item in list1)
{
s += item;
}
sw.Stop();
Console.WriteLine("遍歷list的時間" + sw.Elapsed + "結果爲" + s);
sw.Restart();
int w = 0;
foreach (var item in dic)
{
w += item.Value;
}
sw.Stop();
Console.WriteLine("遍歷dic的時間" + sw.Elapsed + "結果爲" + w);
}
public static void Run1()
{
Thread.Sleep(2000);
Console.WriteLine("阻塞2000");
}
public static void Run2()
{
Thread.Sleep(3000);
Console.WriteLine("阻塞3000");
}
/// <summary>
/// 打印並行執行操作
/// </summary>
public void Run1AndRun2()
{
sw.Start();
Parallel.Invoke(Run1, Run2);//並行執行操作方法
sw.Stop();
Console.WriteLine("並行時間:" + sw.ElapsedMilliseconds);
sw.Restart();
Run1();
Run2();
sw.Stop();
Console.WriteLine("run1+run2的時間" + sw.ElapsedMilliseconds);
}
/// <summary>
/// 結束並行操作
/// </summary>
public void BreakOrStop()
{
ConcurrentBag<int> con = new ConcurrentBag<int>();//表示對線程安全的無序集合
sw.Start();
//使用stop
Parallel.For(0, 1000, (i, state) =>
{
if (con.Count() == 300)
{
state.Stop();
return;
}
con.Add(i);
});
sw.Stop();
Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);
sw.Restart();
//使用break
Parallel.For(0, 1000, (i, state) =>
{
if (con.Count() == 300)
{
state.Break();
return;
}
con.Add(i);
});
sw.Stop();
Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);
}
#endregion
}
/// <summary>
/// 並行Linq
/// </summary>
public class ParallelLinq
{
Stopwatch sq = new Stopwatch();
List<Custom> ListByCustom = new List<Custom>();
public void Plinq()
{
try
{
for (int i = 0; i < 2000000; i++)
{
ListByCustom.Add(new Custom { Adress = "adress" + i, Age = i, Name = "namne" + i });
}
#region AsParallel()表示 把當前查詢並行化
sq.Start();
var list = ListByCustom.Where(i => i.Age > 55).ToList();
sq.Stop();
Console.WriteLine("普通linq時間爲" + sq.ElapsedMilliseconds);
sq.Restart();
sq.Start();
//AsParallel()表示 把當前查詢並行化
var list1 = ListByCustom.AsParallel().Where(i => i.Age > 55).ToList();
sq.Stop();
Console.WriteLine("並行Linq時間爲" + sq.ElapsedMilliseconds);
#endregion
#region Group 與ToLookup
sq.Restart();
var listgroup = ListByCustom.GroupBy(i => i.Age).ToList();
sq.Stop();
Console.WriteLine("Group時間"+sq.ElapsedMilliseconds);
sq.Restart();
var listgroup1 = ListByCustom.ToLookup(i => i.Age).ToList();
sq.Stop();
Console.WriteLine("ToLookup時間" + sq.ElapsedMilliseconds);
#endregion
}
catch (ArgumentNullException ex)
{
Console.WriteLine(ex);
sq.Stop();
}
}
/// <summary>
/// 並行輔助類
/// </summary>
public class Custom
{
public string Name { get; set; }
public int Age { get; set; }
public string Adress { get; set; }
}
}
/// <summary>
/// Task任務,兩種創建方式
/// var t1=new Task(()=>{直接new
///
/// });
///
/// var t2=Task.Factory.StartNew(()=>{工廠模式創建
///
/// });
/// </summary>
public class GetTask {
public void GetTasks() {
//第一種創建方式 必須手動start
var t1 = new Task(() => {
Console.WriteLine("開始t1");
Thread.Sleep(1000);//阻塞1秒
Console.WriteLine("task1");
});
t1.Start();//使用new方式創建時必須手動start
///Task.Wait()等待線程完成,Task.WaiitAll()等待所有線程完成
///
t1.Wait();//等待當前線程完成才執行其他代碼
//第二種方式直接開啓
var t2 = Task.Factory.StartNew(() => {
Console.WriteLine("開始t2");
Thread.Sleep(2000);
Console.WriteLine("task2");
});
var t3 = Task.Factory.StartNew(() => {
Console.WriteLine("開始t3");
Thread.Sleep(2000);
Console.WriteLine("task3");
});
//等待所有的線程完成才執行其他代碼
//Task.WaitAll(t2,t3);
//等效的還有Task.WaitAny,表示任意線程執行完後才執行
//ContinueWith自動執行
Console.WriteLine("線程完成");
var result = t1.ContinueWith(task => {
Console.WriteLine("自動線程");
return "this is result";
});
Console.WriteLine(result.Result.ToString());
#region Task嵌套 TaskCreationOptions.AttachedToParent指定將任務附加到當前結構層次的父級 qt與pt對比
var qt = Task.Factory.StartNew(() => {
var qt1 = Task.Factory.StartNew(() => {
Thread.Sleep(1000);
Console.WriteLine("this is Child1");
});
Console.WriteLine("parent task1");
});
qt.Wait();
Console.WriteLine("當前操作主任務qt並不會等待子任務qt1執行完纔打印此消息");
var pt = Task.Factory.StartNew(() =>
{
var pt1 = Task.Factory.StartNew(() => {
Thread.Sleep(1000);
Console.WriteLine("this is Child2");
},TaskCreationOptions.AttachedToParent);
Console.WriteLine("parent Task2");
});
pt.Wait();
Console.WriteLine("主任務等待子任務執行完纔打印此消息,關鍵字的作用TaskCreationOptions.AttachedToParent");
#endregion
Console.WriteLine("----------------------------------------------------------------");
#region Task嵌套例子
//描述:
//C1得到主任務返回的1+2
//C2得到主任務返回的1+3
//C1的子任務的到C1的結果加上4
//最後,將任務合併,輸出結果
var Ztsk = Task.Factory.StartNew<int>(() => {
Console.WriteLine("開始主任務");
return 1;
});
//等待主任務完成
Console.WriteLine("結果"+Ztsk.Result);
Ztsk.Wait();
//任務C2
var C2 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始任務C2");
return Ztsk.Result + 3;
});
Console.WriteLine("結果"+C2.Result);
//任務C1
var C1 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始任務C1");
return Ztsk.Result + 2;
}).ContinueWith<int>(task => {
Console.WriteLine("開始任務C1的子任務");
return task.Result + 4;
});
Console.WriteLine("結果" + C1.Result);
//等待所有任務完成
Task.WaitAll(C1,C2);
//打印結果
Console.WriteLine("結果爲"+(C2.Result+ C1.Result));
#endregion
Console.WriteLine("-----------------------------Task多線程問題 -----------------------------------");
}
#region Task多線程問題
/* 1,死鎖
如果我們在調用Task.WaitAll方法等待所有線程時
* ,如果有一個Task一直不返回,會出現什麼情況呢?
* 當然,如果我們不做出來的話,程序會一直等待下去,
* 那麼因爲這一個Task的死鎖,導致其他的任務也無法正常提交
* ,整個程序"死"在那裏
*/
#region //死鎖例子
public void TaskError()
{var ts1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("死鎖任務");
while (true)
{
Console.WriteLine("1");
}
});
var ts2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 2");
Thread.Sleep(1000);
Console.WriteLine("結束任務");
});
Task.WaitAll(ts1, ts2);
}
#endregion
#region //解決死鎖,即設定最大等待時間,操過時間就退出
public void RemoveSs() {
Task[] task = new Task[2];
task[0] = Task.Factory.StartNew(() => {
Console.WriteLine("Task 1 Start running...");
while (true)
{
Thread.Sleep(3000);
Console.WriteLine("Task 1 Finished!");
}
});
task[1] = Task.Factory.StartNew(() => {
Console.WriteLine("Task 2 Start running...");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 2 Finished!");
});
//等待的最大時間 爲5秒
Task.WaitAll(task,5000);
for (int i = 0; i < task.Length; i++)
{
if (task[i].Status!=TaskStatus.RanToCompletion)
{
Console.WriteLine("任務{0}沒有執行完",task[i].Id);
}
}
}
#endregion
#endregion
#region 計算例子
public void GetResult() {
bool su = false;
var t1 = Task.Factory.StartNew<int>(() => {
Console.WriteLine("第一個數字");
return 1;
});
t1.Wait();
var t2 = Task.Factory.StartNew<int>(() =>
{
Console.WriteLine("開始計算");
return 5;
}).ContinueWith(state => {
if ((t1.Result + state.Result) >= 6)
Console.WriteLine("大於");
else
{
Console.WriteLine("不大於");
}
});
}
#endregion
}