《C#并行编程高级教程》第3章 命令式任务并行 笔记
Task的使用
var t1 = new Task(() => GenerateAESKeys());
var t2 = new Task(() => GenerateMD5Hashes());
// Start the tasks
t1.Start();
t2.Start();
// Wait for all the tasks to finish
Task.WaitAll(t1, t2);
var t2 = new Task(() => GenerateMD5Hashes());
// Start the tasks
t1.Start();
t2.Start();
// Wait for all the tasks to finish
Task.WaitAll(t1, t2);
等待超时
// Wait for all the tasks to finish with a 1 second timeout
if (!Task.WaitAll(new Task[] { t1, t2 }, 1000))
{
//...
}
if (!Task.WaitAll(new Task[] { t1, t2 }, 1000))
{
//...
}
取消任务
使用CancellationToken,在取消时会抛出OperationCanceledException异常
private static void GenerateAESKeysCancel(System.Threading.CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
var aesM = new AesManaged();
for (int i = 1; i <= NUM_AES_KEYS; i++)
{
aesM.GenerateKey();
byte[] result = aesM.Key;
string hexString = ConvertToHexString(result);
// Console.WriteLine("AES KEY: {0} ", hexString);
ct.ThrowIfCancellationRequested();
}
}
{
ct.ThrowIfCancellationRequested();
var aesM = new AesManaged();
for (int i = 1; i <= NUM_AES_KEYS; i++)
{
aesM.GenerateKey();
byte[] result = aesM.Key;
string hexString = ConvertToHexString(result);
// Console.WriteLine("AES KEY: {0} ", hexString);
ct.ThrowIfCancellationRequested();
}
}
异常处理
try
{
//...
}
catch (AggregateException ex)
{
foreach (Exception innerEx in ex.InnerExceptions)
{
Debug.WriteLine(innerEx.ToString());
// Do something considering the innerEx Exception
}
}
{
//...
}
catch (AggregateException ex)
{
foreach (Exception innerEx in ex.InnerExceptions)
{
Debug.WriteLine(innerEx.ToString());
// Do something considering the innerEx Exception
}
}
任务返回值
使用Task<TResult>创建的任务在Reault属性中可以保存返回值
var cts = new System.Threading.CancellationTokenSource();
var ct = cts.Token;
var t1 = Task.Factory.StartNew(
() => GenerateAESKeysWithCharPrefix(ct, 'A'), ct);
t1.Wait();
for (int i = 0; i < t1.Result.Count; i++)
{
Console.WriteLine(t1.Result[i]);
}
private static List<String> GenerateAESKeysWithCharPrefix(
System.Threading.CancellationToken ct, char prefix)
{
var aesM = new AesManaged();
var keysList = new List<String>();
for (int i = 1; i <= NUM_AES_KEYS; i++)
{
aesM.GenerateKey();
byte[] result = aesM.Key;
string hexString = ConvertToHexString(result);
if (hexString[0] == prefix)
{
keysList.Add(hexString);
}
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
}
return keysList;
}
var ct = cts.Token;
var t1 = Task.Factory.StartNew(
() => GenerateAESKeysWithCharPrefix(ct, 'A'), ct);
t1.Wait();
for (int i = 0; i < t1.Result.Count; i++)
{
Console.WriteLine(t1.Result[i]);
}
private static List<String> GenerateAESKeysWithCharPrefix(
System.Threading.CancellationToken ct, char prefix)
{
var aesM = new AesManaged();
var keysList = new List<String>();
for (int i = 1; i <= NUM_AES_KEYS; i++)
{
aesM.GenerateKey();
byte[] result = aesM.Key;
string hexString = ConvertToHexString(result);
if (hexString[0] == prefix)
{
keysList.Add(hexString);
}
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
}
return keysList;
}
串联任务
var cts = new System.Threading.CancellationTokenSource();
var ct = cts.Token;
var t1 = Task.Factory.StartNew(
() => GenerateAESKeysWithCharPrefix(ct, 'A'), ct);
var t2 = t1.ContinueWith((t) =>
{
for (int i = 0; i < t.Result.Count; i++)
{
Console.WriteLine(t.Result[i]);
}
});
var ct = cts.Token;
var t1 = Task.Factory.StartNew(
() => GenerateAESKeysWithCharPrefix(ct, 'A'), ct);
var t2 = t1.ContinueWith((t) =>
{
for (int i = 0; i < t.Result.Count; i++)
{
Console.WriteLine(t.Result[i]);
}
});