Parallel.Invoke(Run1, Run2); // 儘可能並行執行提供的每個操作。
//執行 for(在 Visual Basic 中爲 For)循環,其中可能會並行運行迭代。
Object obj = new object();
int num = 0;
Parallel.For(0, 1000, i =>
{
int sum = 0;
for (int j = 0; j < 1000; j++)
{
sum += j;
//Parallel.For由於是並行運行的,所以會同時訪問全局變量num,爲了得到正確的結果,要使用lock;
// 這時並行會很慢,這主要是由於並行同時訪問全局變量,會出現資源爭奪,大多數時間消耗在了資源等待上面。
lock (obj)
{
num++;
}
}
});
//數據小或者要訪問全局變量時不推薦使用; Parallel.ForEach用法類似
中途退出並行循環
ConcurrentBag<int> bag = new ConcurrentBag<int>();
Random rdm = new Random();
Parallel.For(0, 1000, (i, state) =>
{
Thread.Sleep(rdm.Next(10, 100));
if (bag.Count == 300)
{
state.Stop();
// state.Break();
return;
}
bag.Add(i);
});
並行的異常捕獲
public void Run1()
{
Thread.Sleep(1000);
Console.WriteLine("Task 1 is cost 2 sec");
throw new Exception("Exception in task 1");
}
public void Run2()
{
Thread.Sleep(3000);
Console.WriteLine("Task 2 is cost 3 sec");
throw new Exception("Exception in task 2");
}
try
{
Parallel.Invoke(Run2, Run1);
}
catch (AggregateException aex)
{
foreach (var ex in aex.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
//如果用Exception也能捕獲到,但是得轉成AggregateException才能點出InnerExceptions獲取異常的具體信息,不然ex.Message的信息是"一個或多個異常"
指定使用的硬件線程數
var bag = new ConcurrentBag<int>();
ParallelOptions options = new ParallelOptions();
//指定使用的硬件線程數
options.MaxDegreeOfParallelism = Environment.ProcessorCount-1;
stopWatch.Restart();
Parallel.For(0, 9000000, options, i =>
{
bag.Add(i);
});
stopWatch.Stop();
Console.WriteLine("並行計算:集合有:{0}", bag.Count + ", " + stopWatch.ElapsedMilliseconds);
Console.ReadKey();
Task
Wait
var task1 = new Task(() =>
{
Console.WriteLine("Task 1 Begin");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 1 Finish");
});
var task2 = new Task(() =>
{
Console.WriteLine("Task 2 Begin");
System.Threading.Thread.Sleep(5000);
Console.WriteLine("Task 2 Finish");
});
Console.WriteLine("Before start:" + task1.Status);
task1.Start();
task2.Start();
Console.WriteLine("After start:" + task1.Status);
task1.Wait(); //等待Task1完成了纔會往下走
Console.WriteLine("After Finish:" + task1.Status);
Task.WaitAny(task1, task2); //等待Task1,Task2任意一個完成了纔會往下走
Task.WaitAll(task1, task2); //等待Task1,Task2都完成了纔會往下走
Console.WriteLine("All task finished!");
Console.ReadKey();
ContinueWith
var task1 = new Task(() =>
{
Console.WriteLine("Task 1 Begin");
Thread.Sleep(2000);
Console.WriteLine("Task 1 Finish");
});
var task2 = new Task(() =>
{
Console.WriteLine("Task 2 Begin");
Thread.Sleep(3000);
Console.WriteLine("Task 2 Finish");
});
task1.Start();
task2.Start();
var result = task1.ContinueWith<string>(task =>
{
Console.WriteLine("task1 finished!");
return "This is task result!";
});
Console.WriteLine(result.Result.ToString());
Console.ReadKey();
///在每次調用ContinueWith方法時,每次會把上次Task的引用傳入進來,以便檢測上次Task的狀態,比如我們可以使用上次Task的Result屬性來獲取返回值。
var SendFeedBackTask = Task.Factory.StartNew(() => { Console.WriteLine("Get some Data!"); })
.ContinueWith<bool>(s => { return true; })
.ContinueWith<string>(r =>
{
if (r.Result)
{
return "Finished";
}
else
{
return "Error";
}
});
Console.WriteLine(SendFeedBackTask.Result);
Console.ReadKey();
取消任務
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var task = Task.Factory.StartNew(() =>
{
for (var i = 0; i < 1000; i++)
{
Thread.Sleep(100);
Console.WriteLine("Abort mission !");
if (token.IsCancellationRequested)
{
Console.WriteLine("Abort mission success!");
return;
}
}
}, token);
token.Register(() =>
{
Console.WriteLine("Canceled");
});
Console.ReadKey();
Console.WriteLine("Press enter to cancel task...");
tokenSource.Cancel();
Console.ReadKey();
屏障同步:使多個任務能夠採用並行方式在多個階段中協同工作
public static void Barrier()
{
Task[] tasks = new Task[4];
Barrier barrier = null;
//表示tasks.Lengt個Task到達屏障纔可以繼續執行
barrier = new Barrier(tasks.Length, (i) =>
{
Console.WriteLine("**********************************************************");
Console.WriteLine("\n屏障中當前階段編號:{0}\n", i.CurrentPhaseNumber);
Console.WriteLine("**********************************************************");
});
for (int j = 0; j < tasks.Length; j++)
{
tasks[j] = Task.Factory.StartNew((obj) =>
{
var single = Convert.ToInt32(obj);
LoadUser(single);
barrier.SignalAndWait(); //發出參與者已達到屏障並等待所有其他參與者也達到屏障。
LoadUser(single);
barrier.SignalAndWait();
LoadProduct(single);
barrier.SignalAndWait();
LoadOrder(single);
barrier.SignalAndWait();
}, j);
}
Console.ReadKey();
}
static void LoadUser(int num)
{
Console.WriteLine("當前任務:{0}正在加載User部分數據!", num);
}
static void LoadProduct(int num)
{
Console.WriteLine("當前任務:{0}正在加載Product部分數據!", num);
}
static void LoadOrder(int num)
{
Console.WriteLine("當前任務:{0}正在加載Order部分數據!", num);
}