/// <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多線程問題
#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
}